@gendive/chatllm 0.17.30 → 0.17.32

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.
@@ -1031,13 +1031,25 @@ ${config.description}`;
1031
1031
 
1032
1032
  ${skillDescriptions}
1033
1033
 
1034
- **\uADDC\uCE59:**
1034
+ **\uD544\uC218 \uADDC\uCE59:**
1035
1035
  - \uC774\uBBF8\uC9C0 \uC0DD\uC131/\uADF8\uB9BC/\uC77C\uB7EC\uC2A4\uD2B8 \uC694\uCCAD \u2192 \uBC18\uB4DC\uC2DC generate_image \uB3C4\uAD6C \uD638\uCD9C
1036
1036
  - \uCD5C\uC2E0 \uC815\uBCF4/\uAC80\uC0C9/\uB274\uC2A4 \uC694\uCCAD \u2192 \uBC18\uB4DC\uC2DC web_search \uB3C4\uAD6C \uD638\uCD9C
1037
- - \uB3C4\uAD6C \uD638\uCD9C \uC2DC \uC9E7\uC740 \uC548\uB0B4 \uBA54\uC2DC\uC9C0\uB97C \uBA3C\uC800 \uC791\uC131\uD558\uACE0, \uADF8 \uB4A4\uC5D0 skill_use \uD0DC\uADF8\uB97C \uD3EC\uD568\uD558\uC138\uC694
1038
1037
  - \uD55C \uBC88\uC5D0 \uD558\uB098\uC758 \uB3C4\uAD6C\uB9CC \uD638\uCD9C\uD558\uC138\uC694
1039
- - \uB3C4\uAD6C \uC5C6\uC774 \uD14D\uC2A4\uD2B8\uB85C\uB9CC \uB2F5\uBCC0\uD558\uC9C0 \uB9C8\uC138\uC694 (\uD574\uB2F9 \uB3C4\uAD6C\uAC00 \uC788\uB294 \uACBD\uC6B0)
1040
- - \uB3C4\uAD6C\uAC00 \uC2E4\uD589\uB418\uBA74 \uACB0\uACFC\uAC00 \uC790\uB3D9\uC73C\uB85C \uC804\uB2EC\uB429\uB2C8\uB2E4`;
1038
+ - \uB3C4\uAD6C\uAC00 \uC2E4\uD589\uB418\uBA74 \uACB0\uACFC\uAC00 \uC790\uB3D9\uC73C\uB85C \uC804\uB2EC\uB429\uB2C8\uB2E4
1039
+
1040
+ **\u26A0\uFE0F \uC808\uB300 \uAE08\uC9C0 \u2014 \uB9D0\uB85C\uB9CC \uC124\uBA85\uD558\uACE0 \uD0DC\uADF8\uB97C \uC0DD\uB7B5\uD558\uB294 \uD589\uC704:**
1041
+ "\uAC80\uC0C9\uD558\uACA0\uC2B5\uB2C8\uB2E4", "\uCC3E\uC544\uBCF4\uACA0\uC2B5\uB2C8\uB2E4", "\uC870\uC0AC\uD574 \uBCF4\uACA0\uC2B5\uB2C8\uB2E4", "\uC774\uBBF8\uC9C0\uB97C \uC0DD\uC131\uD558\uACA0\uC2B5\uB2C8\uB2E4" \uB4F1
1042
+ **\uB9D0\uB85C\uB9CC \uC758\uB3C4\uB97C \uBC1D\uD788\uACE0 <skill_use> \uD0DC\uADF8\uB97C \uD3EC\uD568\uD558\uC9C0 \uC54A\uC73C\uBA74 \uB3C4\uAD6C\uAC00 \uC2E4\uD589\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.**
1043
+ \uBC18\uB4DC\uC2DC \uD14D\uC2A4\uD2B8 \uC548\uB0B4 \uC9C1\uD6C4\uC5D0 <skill_use> \uD0DC\uADF8\uB97C \uCD9C\uB825\uD574\uC57C \uD569\uB2C8\uB2E4.
1044
+
1045
+ \u274C \uC798\uBABB\uB41C \uC608 (\uD0DC\uADF8 \uC5C6\uC774 \uB9D0\uB9CC \uD568 \u2014 \uB3C4\uAD6C \uC2E4\uD589 \uC548 \uB428):
1046
+ "\uB124, \uB370\uBE0C\uB2E4\uC774\uBE0C\uC5D0 \uB300\uD574 \uAC80\uC0C9\uD574 \uBCF4\uACA0\uC2B5\uB2C8\uB2E4."
1047
+
1048
+ \u2705 \uC62C\uBC14\uB978 \uC608 (\uC548\uB0B4 + \uD0DC\uADF8 \uD3EC\uD568 \u2014 \uB3C4\uAD6C \uC2E4\uD589\uB428):
1049
+ "\uB370\uBE0C\uB2E4\uC774\uBE0C\uC5D0 \uB300\uD574 \uAC80\uC0C9\uD558\uACA0\uC2B5\uB2C8\uB2E4.
1050
+ <skill_use name="web_search">{"query": "\uB370\uBE0C\uB2E4\uC774\uBE0C"}</skill_use>"
1051
+
1052
+ **\uBC18\uBCF5: \uD574\uB2F9 \uB3C4\uAD6C\uAC00 \uC788\uB2E4\uBA74, <skill_use> \uD0DC\uADF8 \uC5C6\uC774 \uC808\uB300 \uC751\uB2F5\uD558\uC9C0 \uB9C8\uC138\uC694.**`;
1041
1053
  }, [resolvedSkills]);
1042
1054
  const handleSkillCall = (0, import_react3.useCallback)(
1043
1055
  async (content, callbacks) => {
@@ -2955,6 +2967,7 @@ ${attachmentContext}
2955
2967
  }
2956
2968
  if (detectedSkill && !resolvedSkills[detectedSkill.name]) {
2957
2969
  console.warn(`[useChatUI] \uC2A4\uD0AC "${detectedSkill.name}" \uAC10\uC9C0\uB418\uC5C8\uC73C\uB098 \uBBF8\uB4F1\uB85D. \uB4F1\uB85D\uB41C \uC2A4\uD0AC:`, Object.keys(resolvedSkills));
2970
+ accumulatedContent = skillCleanContent;
2958
2971
  setSessions(
2959
2972
  (prev) => prev.map((s) => {
2960
2973
  if (s.id !== capturedSessionId) return s;
@@ -2969,84 +2982,157 @@ ${attachmentContext}
2969
2982
  );
2970
2983
  }
2971
2984
  if (detectedSkill && resolvedSkills[detectedSkill.name]) {
2972
- setSessions(
2973
- (prev) => prev.map((s) => {
2974
- if (s.id !== capturedSessionId) return s;
2975
- return {
2976
- ...s,
2977
- messages: s.messages.map((m) => {
2978
- if (m.id !== assistantMessageId) return m;
2979
- return {
2980
- ...m,
2981
- content: skillCleanContent,
2982
- skillExecution: {
2983
- skillName: detectedSkill.name,
2984
- params: detectedSkill.params,
2985
- status: "executing"
2986
- }
2987
- };
2988
- })
2989
- };
2990
- })
2991
- );
2992
- let streamedReport = "";
2993
- const { result } = await handleSkillCall(assistantContent, {
2994
- onProgress: (progress) => {
2995
- setSessions(
2996
- (prev) => prev.map((s) => {
2997
- if (s.id !== capturedSessionId) return s;
2998
- return {
2999
- ...s,
3000
- messages: s.messages.map((m) => {
3001
- if (m.id !== assistantMessageId) return m;
3002
- return {
3003
- ...m,
3004
- skillExecution: { ...m.skillExecution, progress }
3005
- };
3006
- })
3007
- };
3008
- })
3009
- );
3010
- },
3011
- onStream: (chunk) => {
3012
- streamedReport += chunk;
3013
- setSessions(
3014
- (prev) => prev.map((s) => {
3015
- if (s.id !== capturedSessionId) return s;
3016
- return {
3017
- ...s,
3018
- messages: s.messages.map((m) => {
3019
- if (m.id !== assistantMessageId) return m;
3020
- return { ...m, content: streamedReport };
3021
- })
3022
- };
3023
- })
3024
- );
3025
- },
3026
- signal: abortControllerRef.current?.signal
3027
- });
3028
- if (result) {
3029
- if (result.metadata?.__toolResult__) {
3030
- const resultType = result.metadata.resultType;
3031
- const toolName = result.metadata.toolName;
3032
- const toolLabel = result.metadata.toolLabel;
3033
- const toolIcon = result.metadata.toolIcon;
3034
- const parts = [];
3035
- if (skillCleanContent.trim()) {
3036
- parts.push({ type: "text", content: skillCleanContent });
2985
+ if (activeChecklistRef.current) {
2986
+ console.log("[useChatUI] \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uB2E8\uACC4 \uB0B4 \uC2A4\uD0AC \uC2E4\uD589:", detectedSkill.name);
2987
+ accumulatedContent = skillCleanContent;
2988
+ setSessions(
2989
+ (prev) => prev.map((s) => {
2990
+ if (s.id !== capturedSessionId) return s;
2991
+ return { ...s, messages: s.messages.map((m) => m.id !== assistantMessageId ? m : { ...m, content: skillCleanContent }) };
2992
+ })
2993
+ );
2994
+ try {
2995
+ const { result: skillResult } = await handleSkillCall(assistantContent, {
2996
+ signal: abortControllerRef.current?.signal
2997
+ });
2998
+ if (skillResult?.content) {
2999
+ accumulatedContent = skillResult.content;
3037
3000
  }
3038
- parts.push({
3039
- type: "tool_result",
3040
- toolName,
3041
- label: toolLabel,
3042
- icon: toolIcon,
3043
- result: {
3044
- type: resultType,
3045
- content: result.content,
3046
- metadata: result.metadata,
3047
- sources: result.sources
3001
+ } catch (e) {
3002
+ console.warn("[useChatUI] \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uB0B4 \uC2A4\uD0AC \uC2E4\uD589 \uC2E4\uD328:", e);
3003
+ }
3004
+ } else {
3005
+ setSessions(
3006
+ (prev) => prev.map((s) => {
3007
+ if (s.id !== capturedSessionId) return s;
3008
+ return {
3009
+ ...s,
3010
+ messages: s.messages.map((m) => {
3011
+ if (m.id !== assistantMessageId) return m;
3012
+ return {
3013
+ ...m,
3014
+ content: skillCleanContent,
3015
+ skillExecution: {
3016
+ skillName: detectedSkill.name,
3017
+ params: detectedSkill.params,
3018
+ status: "executing"
3019
+ }
3020
+ };
3021
+ })
3022
+ };
3023
+ })
3024
+ );
3025
+ let streamedReport = "";
3026
+ const { result } = await handleSkillCall(assistantContent, {
3027
+ onProgress: (progress) => {
3028
+ setSessions(
3029
+ (prev) => prev.map((s) => {
3030
+ if (s.id !== capturedSessionId) return s;
3031
+ return {
3032
+ ...s,
3033
+ messages: s.messages.map((m) => {
3034
+ if (m.id !== assistantMessageId) return m;
3035
+ return {
3036
+ ...m,
3037
+ skillExecution: { ...m.skillExecution, progress }
3038
+ };
3039
+ })
3040
+ };
3041
+ })
3042
+ );
3043
+ },
3044
+ onStream: (chunk) => {
3045
+ streamedReport += chunk;
3046
+ setSessions(
3047
+ (prev) => prev.map((s) => {
3048
+ if (s.id !== capturedSessionId) return s;
3049
+ return {
3050
+ ...s,
3051
+ messages: s.messages.map((m) => {
3052
+ if (m.id !== assistantMessageId) return m;
3053
+ return { ...m, content: streamedReport };
3054
+ })
3055
+ };
3056
+ })
3057
+ );
3058
+ },
3059
+ signal: abortControllerRef.current?.signal
3060
+ });
3061
+ if (result) {
3062
+ if (result.metadata?.__toolResult__) {
3063
+ const resultType = result.metadata.resultType;
3064
+ const toolName = result.metadata.toolName;
3065
+ const toolLabel = result.metadata.toolLabel;
3066
+ const toolIcon = result.metadata.toolIcon;
3067
+ const parts = [];
3068
+ if (skillCleanContent.trim()) {
3069
+ parts.push({ type: "text", content: skillCleanContent });
3048
3070
  }
3049
- });
3071
+ parts.push({
3072
+ type: "tool_result",
3073
+ toolName,
3074
+ label: toolLabel,
3075
+ icon: toolIcon,
3076
+ result: {
3077
+ type: resultType,
3078
+ content: result.content,
3079
+ metadata: result.metadata,
3080
+ sources: result.sources
3081
+ }
3082
+ });
3083
+ setSessions(
3084
+ (prev) => prev.map((s) => {
3085
+ if (s.id !== capturedSessionId) return s;
3086
+ return {
3087
+ ...s,
3088
+ messages: s.messages.map((m) => {
3089
+ if (m.id !== assistantMessageId) return m;
3090
+ return {
3091
+ ...m,
3092
+ contentParts: parts,
3093
+ skillExecution: {
3094
+ ...m.skillExecution,
3095
+ status: "done",
3096
+ result
3097
+ }
3098
+ };
3099
+ })
3100
+ };
3101
+ })
3102
+ );
3103
+ if (resultType === "image" || resultType === "file") {
3104
+ saveMessagesOnEarlyReturn();
3105
+ setIsLoading(false);
3106
+ abortControllerRef.current = null;
3107
+ return;
3108
+ }
3109
+ let shouldContinue = continueAfterToolResult;
3110
+ if (onSkillCompleteRef.current) {
3111
+ const decision = onSkillCompleteRef.current(toolName, result);
3112
+ shouldContinue = decision === "continue";
3113
+ }
3114
+ if (!shouldContinue) {
3115
+ saveMessagesOnEarlyReturn();
3116
+ setIsLoading(false);
3117
+ abortControllerRef.current = null;
3118
+ return;
3119
+ }
3120
+ skipNextSkillParsingRef.current = true;
3121
+ saveMessagesOnEarlyReturn();
3122
+ const feedbackPrompt = resultType === "error" ? `\uB3C4\uAD6C "${toolName}" \uC2E4\uD589 \uC911 \uC624\uB958 \uBC1C\uC0DD: ${result.content}
3123
+
3124
+ \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC624\uB958\uB97C \uC548\uB0B4\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.` : `\uB3C4\uAD6C "${toolName}" \uACB0\uACFC:
3125
+
3126
+ ${result.content}
3127
+
3128
+ \uC704 \uACB0\uACFC\uB97C \uBC14\uD0D5\uC73C\uB85C \uB2F5\uBCC0\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`;
3129
+ setTimeout(() => {
3130
+ sendMessage(feedbackPrompt, { hiddenUserMessage: true });
3131
+ }, 100);
3132
+ setIsLoading(false);
3133
+ abortControllerRef.current = null;
3134
+ return;
3135
+ }
3050
3136
  setSessions(
3051
3137
  (prev) => prev.map((s) => {
3052
3138
  if (s.id !== capturedSessionId) return s;
@@ -3056,7 +3142,7 @@ ${attachmentContext}
3056
3142
  if (m.id !== assistantMessageId) return m;
3057
3143
  return {
3058
3144
  ...m,
3059
- contentParts: parts,
3145
+ sources: result.sources || m.sources,
3060
3146
  skillExecution: {
3061
3147
  ...m.skillExecution,
3062
3148
  status: "done",
@@ -3067,18 +3153,18 @@ ${attachmentContext}
3067
3153
  };
3068
3154
  })
3069
3155
  );
3070
- if (resultType === "image" || resultType === "file") {
3156
+ if (streamedReport) {
3071
3157
  saveMessagesOnEarlyReturn();
3072
3158
  setIsLoading(false);
3073
3159
  abortControllerRef.current = null;
3074
3160
  return;
3075
3161
  }
3076
- let shouldContinue = continueAfterToolResult;
3162
+ let shouldContinueSkill = continueAfterToolResult;
3077
3163
  if (onSkillCompleteRef.current) {
3078
- const decision = onSkillCompleteRef.current(toolName, result);
3079
- shouldContinue = decision === "continue";
3164
+ const decision = onSkillCompleteRef.current(detectedSkill.name, result);
3165
+ shouldContinueSkill = decision === "continue";
3080
3166
  }
3081
- if (!shouldContinue) {
3167
+ if (!shouldContinueSkill) {
3082
3168
  saveMessagesOnEarlyReturn();
3083
3169
  setIsLoading(false);
3084
3170
  abortControllerRef.current = null;
@@ -3086,70 +3172,18 @@ ${attachmentContext}
3086
3172
  }
3087
3173
  skipNextSkillParsingRef.current = true;
3088
3174
  saveMessagesOnEarlyReturn();
3089
- const feedbackPrompt = resultType === "error" ? `\uB3C4\uAD6C "${toolName}" \uC2E4\uD589 \uC911 \uC624\uB958 \uBC1C\uC0DD: ${result.content}
3090
-
3091
- \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC624\uB958\uB97C \uC548\uB0B4\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.` : `\uB3C4\uAD6C "${toolName}" \uACB0\uACFC:
3175
+ const resultPrompt = `\uC2A4\uD0AC "${detectedSkill.name}" \uC2E4\uD589 \uACB0\uACFC:
3092
3176
 
3093
3177
  ${result.content}
3094
3178
 
3095
- \uC704 \uACB0\uACFC\uB97C \uBC14\uD0D5\uC73C\uB85C \uB2F5\uBCC0\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`;
3179
+ \uC704 \uACB0\uACFC\uB97C \uBC14\uD0D5\uC73C\uB85C \uC0AC\uC6A9\uC790\uC758 \uC6D0\uB798 \uC9C8\uBB38\uC5D0 \uB2F5\uBCC0\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`;
3096
3180
  setTimeout(() => {
3097
- sendMessage(feedbackPrompt, { hiddenUserMessage: true });
3181
+ sendMessage(resultPrompt, { hiddenUserMessage: true });
3098
3182
  }, 100);
3099
3183
  setIsLoading(false);
3100
3184
  abortControllerRef.current = null;
3101
3185
  return;
3102
3186
  }
3103
- setSessions(
3104
- (prev) => prev.map((s) => {
3105
- if (s.id !== capturedSessionId) return s;
3106
- return {
3107
- ...s,
3108
- messages: s.messages.map((m) => {
3109
- if (m.id !== assistantMessageId) return m;
3110
- return {
3111
- ...m,
3112
- sources: result.sources || m.sources,
3113
- skillExecution: {
3114
- ...m.skillExecution,
3115
- status: "done",
3116
- result
3117
- }
3118
- };
3119
- })
3120
- };
3121
- })
3122
- );
3123
- if (streamedReport) {
3124
- saveMessagesOnEarlyReturn();
3125
- setIsLoading(false);
3126
- abortControllerRef.current = null;
3127
- return;
3128
- }
3129
- let shouldContinueSkill = continueAfterToolResult;
3130
- if (onSkillCompleteRef.current) {
3131
- const decision = onSkillCompleteRef.current(detectedSkill.name, result);
3132
- shouldContinueSkill = decision === "continue";
3133
- }
3134
- if (!shouldContinueSkill) {
3135
- saveMessagesOnEarlyReturn();
3136
- setIsLoading(false);
3137
- abortControllerRef.current = null;
3138
- return;
3139
- }
3140
- skipNextSkillParsingRef.current = true;
3141
- saveMessagesOnEarlyReturn();
3142
- const resultPrompt = `\uC2A4\uD0AC "${detectedSkill.name}" \uC2E4\uD589 \uACB0\uACFC:
3143
-
3144
- ${result.content}
3145
-
3146
- \uC704 \uACB0\uACFC\uB97C \uBC14\uD0D5\uC73C\uB85C \uC0AC\uC6A9\uC790\uC758 \uC6D0\uB798 \uC9C8\uBB38\uC5D0 \uB2F5\uBCC0\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`;
3147
- setTimeout(() => {
3148
- sendMessage(resultPrompt, { hiddenUserMessage: true });
3149
- }, 100);
3150
- setIsLoading(false);
3151
- abortControllerRef.current = null;
3152
- return;
3153
3187
  }
3154
3188
  }
3155
3189
  }