@orbe-agro/client-core 5.6.239 → 5.6.241
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/@ecme/assets/styles/app.css +116 -3
- package/dist/@ecme/assets/styles/tailwind/index.css +119 -3
- package/dist/@ecme/components/template/Footer.js +1 -1
- package/dist/@ecme/components/template/OrbeAiWidget/OrbeAiWidget.js +0 -2
- package/dist/@ecme/components/template/OrbeAiWidget/OrbeAiWidget.js.map +1 -1
- package/dist/@ecme/components/view/ChatBox/ChatBox.js +2 -0
- package/dist/@ecme/components/view/ChatBox/ChatBox.js.map +1 -1
- package/dist/@ecme/components/view/ChatBox/components/MessageList.js +2 -1
- package/dist/@ecme/components/view/ChatBox/components/MessageList.js.map +1 -1
- package/dist/@ecme/index.js +3 -4
- package/dist/@ecme/services/AiService.js +53 -24
- package/dist/@ecme/services/AiService.js.map +1 -1
- package/dist/@ecme/services/aiAuthHeaders.js +35 -0
- package/dist/@ecme/services/aiAuthHeaders.js.map +1 -0
- package/dist/@ecme/services/axios/AxiosRequestIntrceptorConfigCallback.js +4 -27
- package/dist/@ecme/services/axios/AxiosRequestIntrceptorConfigCallback.js.map +1 -1
- package/dist/@ecme/services/index.js +4 -5
- package/dist/@ecme/services/sseParser.js +42 -0
- package/dist/@ecme/services/sseParser.js.map +1 -0
- package/dist/@ecme/views/concepts/ai/Chat/components/AiErrorMessage.js +15 -0
- package/dist/@ecme/views/concepts/ai/Chat/components/AiErrorMessage.js.map +1 -0
- package/dist/@ecme/views/concepts/ai/Chat/components/ApprovalCard.js +73 -0
- package/dist/@ecme/views/concepts/ai/Chat/components/ApprovalCard.js.map +1 -0
- package/dist/@ecme/views/concepts/ai/Chat/components/ChatView.js +37 -10
- package/dist/@ecme/views/concepts/ai/Chat/components/ChatView.js.map +1 -1
- package/dist/@ecme/views/concepts/ai/Chat/components/ToolCallChip.js +153 -0
- package/dist/@ecme/views/concepts/ai/Chat/components/ToolCallChip.js.map +1 -0
- package/dist/@ecme/views/concepts/ai/Chat/components/toolPresentation.js +99 -0
- package/dist/@ecme/views/concepts/ai/Chat/components/toolPresentation.js.map +1 -0
- package/dist/@ecme/views/concepts/ai/Chat/hooks/useChatSend.js +111 -17
- package/dist/@ecme/views/concepts/ai/Chat/hooks/useChatSend.js.map +1 -1
- package/dist/@ecme/views/concepts/ai/Chat/store/generativeChatStore.js +29 -13
- package/dist/@ecme/views/concepts/ai/Chat/store/generativeChatStore.js.map +1 -1
- package/dist/@types/@ecme/components/template/OrbeAiWidget/OrbeAiWidget.d.ts.map +1 -1
- package/dist/@types/@ecme/components/view/ChatBox/ChatBox.d.ts.map +1 -1
- package/dist/@types/@ecme/components/view/ChatBox/components/MessageList.d.ts +2 -0
- package/dist/@types/@ecme/components/view/ChatBox/components/MessageList.d.ts.map +1 -1
- package/dist/@types/@ecme/services/AiService.d.ts +28 -15
- package/dist/@types/@ecme/services/AiService.d.ts.map +1 -1
- package/dist/@types/@ecme/services/aiAuthHeaders.d.ts +12 -0
- package/dist/@types/@ecme/services/aiAuthHeaders.d.ts.map +1 -0
- package/dist/@types/@ecme/services/axios/AxiosRequestIntrceptorConfigCallback.d.ts +6 -0
- package/dist/@types/@ecme/services/axios/AxiosRequestIntrceptorConfigCallback.d.ts.map +1 -1
- package/dist/@types/@ecme/services/sseParser.d.ts +20 -0
- package/dist/@types/@ecme/services/sseParser.d.ts.map +1 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/AiErrorMessage.d.ts +8 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/AiErrorMessage.d.ts.map +1 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ApprovalCard.d.ts +15 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ApprovalCard.d.ts.map +1 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ChatView.d.ts.map +1 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ToolCallChip.d.ts +7 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ToolCallChip.d.ts.map +1 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/toolPresentation.d.ts +14 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/toolPresentation.d.ts.map +1 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/hooks/useChatSend.d.ts +2 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/hooks/useChatSend.d.ts.map +1 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/store/generativeChatStore.d.ts +1 -0
- package/dist/@types/@ecme/views/concepts/ai/Chat/store/generativeChatStore.d.ts.map +1 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/types.d.ts +96 -23
- package/dist/@types/@ecme/views/concepts/ai/Chat/types.d.ts.map +1 -1
- package/dist/@types/base/@types/models/transportadora/irpf.d.ts +1 -0
- package/dist/@types/base/@types/models/transportadora/irpf.d.ts.map +1 -1
- package/dist/@types/base/@types/models/transportadora/irpfFaixaDesconto.d.ts +0 -1
- package/dist/@types/base/@types/models/transportadora/irpfFaixaDesconto.d.ts.map +1 -1
- package/dist/base/assets/styles/init.css +128 -3
- package/lib/@ecme/components/template/OrbeAiWidget/OrbeAiWidget.tsx +0 -2
- package/lib/@ecme/components/view/ChatBox/ChatBox.tsx +2 -0
- package/lib/@ecme/components/view/ChatBox/components/MessageList.tsx +8 -4
- package/lib/@ecme/services/AiService.ts +89 -44
- package/lib/@ecme/services/aiAuthHeaders.ts +58 -0
- package/lib/@ecme/services/axios/AxiosRequestIntrceptorConfigCallback.ts +10 -39
- package/lib/@ecme/services/sseParser.ts +75 -0
- package/lib/@ecme/views/concepts/ai/Chat/components/AiErrorMessage.tsx +28 -0
- package/lib/@ecme/views/concepts/ai/Chat/components/ApprovalCard.tsx +103 -0
- package/lib/@ecme/views/concepts/ai/Chat/components/ChatView.tsx +74 -10
- package/lib/@ecme/views/concepts/ai/Chat/components/ToolCallChip.tsx +218 -0
- package/lib/@ecme/views/concepts/ai/Chat/components/toolPresentation.ts +137 -0
- package/lib/@ecme/views/concepts/ai/Chat/hooks/useChatSend.ts +175 -23
- package/lib/@ecme/views/concepts/ai/Chat/store/generativeChatStore.ts +41 -13
- package/lib/@ecme/views/concepts/ai/Chat/types.ts +82 -29
- package/lib/base/@types/models/transportadora/irpf.ts +1 -0
- package/lib/base/@types/models/transportadora/irpfFaixaDesconto.ts +0 -1
- package/package.json +1 -1
- package/dist/@ecme/views/concepts/ai/Chat/components/ModelSelect.js +0 -48
- package/dist/@ecme/views/concepts/ai/Chat/components/ModelSelect.js.map +0 -1
- package/dist/@ecme/views/concepts/ai/Chat/store/aiModelStore.js +0 -15
- package/dist/@ecme/views/concepts/ai/Chat/store/aiModelStore.js.map +0 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ModelSelect.d.ts +0 -8
- package/dist/@types/@ecme/views/concepts/ai/Chat/components/ModelSelect.d.ts.map +0 -1
- package/dist/@types/@ecme/views/concepts/ai/Chat/store/aiModelStore.d.ts +0 -25
- package/dist/@types/@ecme/views/concepts/ai/Chat/store/aiModelStore.d.ts.map +0 -1
- package/lib/@ecme/views/concepts/ai/Chat/components/ModelSelect.tsx +0 -66
- package/lib/@ecme/views/concepts/ai/Chat/store/aiModelStore.ts +0 -23
|
@@ -5481,6 +5481,10 @@ video {
|
|
|
5481
5481
|
width: 0.375rem;
|
|
5482
5482
|
height: 0.375rem;
|
|
5483
5483
|
}
|
|
5484
|
+
.size-8{
|
|
5485
|
+
width: 2rem;
|
|
5486
|
+
height: 2rem;
|
|
5487
|
+
}
|
|
5484
5488
|
.h-0{
|
|
5485
5489
|
height: 0px;
|
|
5486
5490
|
}
|
|
@@ -5613,6 +5617,9 @@ video {
|
|
|
5613
5617
|
.max-h-20{
|
|
5614
5618
|
max-height: 5rem;
|
|
5615
5619
|
}
|
|
5620
|
+
.max-h-40{
|
|
5621
|
+
max-height: 10rem;
|
|
5622
|
+
}
|
|
5616
5623
|
.max-h-8{
|
|
5617
5624
|
max-height: 2rem;
|
|
5618
5625
|
}
|
|
@@ -5827,6 +5834,10 @@ video {
|
|
|
5827
5834
|
.w-\[950px\]{
|
|
5828
5835
|
width: 950px;
|
|
5829
5836
|
}
|
|
5837
|
+
.w-fit{
|
|
5838
|
+
width: -moz-fit-content;
|
|
5839
|
+
width: fit-content;
|
|
5840
|
+
}
|
|
5830
5841
|
.w-full{
|
|
5831
5842
|
width: 100%;
|
|
5832
5843
|
}
|
|
@@ -5954,9 +5965,6 @@ video {
|
|
|
5954
5965
|
.max-w-\[900px\]{
|
|
5955
5966
|
max-width: 900px;
|
|
5956
5967
|
}
|
|
5957
|
-
.max-w-\[9rem\]{
|
|
5958
|
-
max-width: 9rem;
|
|
5959
|
-
}
|
|
5960
5968
|
.max-w-full{
|
|
5961
5969
|
max-width: 100%;
|
|
5962
5970
|
}
|
|
@@ -6003,6 +6011,10 @@ video {
|
|
|
6003
6011
|
--tw-translate-y: -50%;
|
|
6004
6012
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
6005
6013
|
}
|
|
6014
|
+
.rotate-180{
|
|
6015
|
+
--tw-rotate: 180deg;
|
|
6016
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
6017
|
+
}
|
|
6006
6018
|
.transform{
|
|
6007
6019
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
6008
6020
|
}
|
|
@@ -6108,6 +6120,9 @@ video {
|
|
|
6108
6120
|
.grid-cols-6{
|
|
6109
6121
|
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
6110
6122
|
}
|
|
6123
|
+
.grid-cols-\[minmax\(0\2c auto\)_minmax\(0\2c 1fr\)\]{
|
|
6124
|
+
grid-template-columns: minmax(0,auto) minmax(0,1fr);
|
|
6125
|
+
}
|
|
6111
6126
|
.grid-rows-3{
|
|
6112
6127
|
grid-template-rows: repeat(3, minmax(0, 1fr));
|
|
6113
6128
|
}
|
|
@@ -6138,6 +6153,9 @@ video {
|
|
|
6138
6153
|
.items-center{
|
|
6139
6154
|
align-items: center;
|
|
6140
6155
|
}
|
|
6156
|
+
.items-baseline{
|
|
6157
|
+
align-items: baseline;
|
|
6158
|
+
}
|
|
6141
6159
|
.\!justify-start{
|
|
6142
6160
|
justify-content: flex-start !important;
|
|
6143
6161
|
}
|
|
@@ -6174,6 +6192,9 @@ video {
|
|
|
6174
6192
|
.gap-2{
|
|
6175
6193
|
gap: 0.5rem;
|
|
6176
6194
|
}
|
|
6195
|
+
.gap-2\.5{
|
|
6196
|
+
gap: 0.625rem;
|
|
6197
|
+
}
|
|
6177
6198
|
.gap-3{
|
|
6178
6199
|
gap: 0.75rem;
|
|
6179
6200
|
}
|
|
@@ -6197,6 +6218,10 @@ video {
|
|
|
6197
6218
|
-moz-column-gap: 0.5rem;
|
|
6198
6219
|
column-gap: 0.5rem;
|
|
6199
6220
|
}
|
|
6221
|
+
.gap-x-3{
|
|
6222
|
+
-moz-column-gap: 0.75rem;
|
|
6223
|
+
column-gap: 0.75rem;
|
|
6224
|
+
}
|
|
6200
6225
|
.gap-x-4{
|
|
6201
6226
|
-moz-column-gap: 1rem;
|
|
6202
6227
|
column-gap: 1rem;
|
|
@@ -6212,6 +6237,9 @@ video {
|
|
|
6212
6237
|
.gap-y-0\.5{
|
|
6213
6238
|
row-gap: 0.125rem;
|
|
6214
6239
|
}
|
|
6240
|
+
.gap-y-1{
|
|
6241
|
+
row-gap: 0.25rem;
|
|
6242
|
+
}
|
|
6215
6243
|
.gap-y-10{
|
|
6216
6244
|
row-gap: 2.5rem;
|
|
6217
6245
|
}
|
|
@@ -6232,6 +6260,14 @@ video {
|
|
|
6232
6260
|
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
|
6233
6261
|
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
|
6234
6262
|
}
|
|
6263
|
+
.divide-y > :not([hidden]) ~ :not([hidden]){
|
|
6264
|
+
--tw-divide-y-reverse: 0;
|
|
6265
|
+
border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
|
|
6266
|
+
border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
|
|
6267
|
+
}
|
|
6268
|
+
.divide-gray-100 > :not([hidden]) ~ :not([hidden]){
|
|
6269
|
+
border-color: var(--gray-100);
|
|
6270
|
+
}
|
|
6235
6271
|
.overflow-auto{
|
|
6236
6272
|
overflow: auto;
|
|
6237
6273
|
}
|
|
@@ -6264,9 +6300,15 @@ video {
|
|
|
6264
6300
|
.whitespace-nowrap{
|
|
6265
6301
|
white-space: nowrap;
|
|
6266
6302
|
}
|
|
6303
|
+
.whitespace-pre-wrap{
|
|
6304
|
+
white-space: pre-wrap;
|
|
6305
|
+
}
|
|
6267
6306
|
.text-nowrap{
|
|
6268
6307
|
text-wrap: nowrap;
|
|
6269
6308
|
}
|
|
6309
|
+
.break-words{
|
|
6310
|
+
overflow-wrap: break-word;
|
|
6311
|
+
}
|
|
6270
6312
|
.break-all{
|
|
6271
6313
|
word-break: break-all;
|
|
6272
6314
|
}
|
|
@@ -6393,6 +6435,10 @@ video {
|
|
|
6393
6435
|
.border-primary{
|
|
6394
6436
|
border-color: var(--primary);
|
|
6395
6437
|
}
|
|
6438
|
+
.border-red-200{
|
|
6439
|
+
--tw-border-opacity: 1;
|
|
6440
|
+
border-color: rgb(254 202 202 / var(--tw-border-opacity, 1));
|
|
6441
|
+
}
|
|
6396
6442
|
.border-success{
|
|
6397
6443
|
border-color: var(--success);
|
|
6398
6444
|
}
|
|
@@ -6930,6 +6976,10 @@ video {
|
|
|
6930
6976
|
padding-left: 0.5rem;
|
|
6931
6977
|
padding-right: 0.5rem;
|
|
6932
6978
|
}
|
|
6979
|
+
.px-2\.5{
|
|
6980
|
+
padding-left: 0.625rem;
|
|
6981
|
+
padding-right: 0.625rem;
|
|
6982
|
+
}
|
|
6933
6983
|
.px-3{
|
|
6934
6984
|
padding-left: 0.75rem;
|
|
6935
6985
|
padding-right: 0.75rem;
|
|
@@ -6986,6 +7036,10 @@ video {
|
|
|
6986
7036
|
padding-top: 0.75rem;
|
|
6987
7037
|
padding-bottom: 0.75rem;
|
|
6988
7038
|
}
|
|
7039
|
+
.py-3\.5{
|
|
7040
|
+
padding-top: 0.875rem;
|
|
7041
|
+
padding-bottom: 0.875rem;
|
|
7042
|
+
}
|
|
6989
7043
|
.py-4{
|
|
6990
7044
|
padding-top: 1rem;
|
|
6991
7045
|
padding-bottom: 1rem;
|
|
@@ -7272,6 +7326,9 @@ video {
|
|
|
7272
7326
|
--tw-text-opacity: 1;
|
|
7273
7327
|
color: rgb(239 68 68 / var(--tw-text-opacity, 1));
|
|
7274
7328
|
}
|
|
7329
|
+
.text-red-500\/90{
|
|
7330
|
+
color: rgb(239 68 68 / 0.9);
|
|
7331
|
+
}
|
|
7275
7332
|
.text-red-600{
|
|
7276
7333
|
--tw-text-opacity: 1;
|
|
7277
7334
|
color: rgb(220 38 38 / var(--tw-text-opacity, 1));
|
|
@@ -7329,6 +7386,9 @@ video {
|
|
|
7329
7386
|
.no-underline{
|
|
7330
7387
|
text-decoration-line: none;
|
|
7331
7388
|
}
|
|
7389
|
+
.underline-offset-2{
|
|
7390
|
+
text-underline-offset: 2px;
|
|
7391
|
+
}
|
|
7332
7392
|
.opacity-0{
|
|
7333
7393
|
opacity: 0;
|
|
7334
7394
|
}
|
|
@@ -7476,6 +7536,11 @@ video {
|
|
|
7476
7536
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
7477
7537
|
transition-duration: 150ms;
|
|
7478
7538
|
}
|
|
7539
|
+
.transition-transform{
|
|
7540
|
+
transition-property: transform;
|
|
7541
|
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
7542
|
+
transition-duration: 150ms;
|
|
7543
|
+
}
|
|
7479
7544
|
.duration-150{
|
|
7480
7545
|
transition-duration: 150ms;
|
|
7481
7546
|
}
|
|
@@ -7613,6 +7678,10 @@ video {
|
|
|
7613
7678
|
content: var(--tw-content);
|
|
7614
7679
|
}
|
|
7615
7680
|
|
|
7681
|
+
.last\:mb-0:last-child{
|
|
7682
|
+
margin-bottom: 0px;
|
|
7683
|
+
}
|
|
7684
|
+
|
|
7616
7685
|
.focus-within\:border-primary:focus-within{
|
|
7617
7686
|
border-color: var(--primary);
|
|
7618
7687
|
}
|
|
@@ -7980,6 +8049,18 @@ video {
|
|
|
7980
8049
|
.motion-safe\:animate-pulse{
|
|
7981
8050
|
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
7982
8051
|
}
|
|
8052
|
+
@keyframes spin{
|
|
8053
|
+
to{
|
|
8054
|
+
transform: rotate(360deg);
|
|
8055
|
+
}
|
|
8056
|
+
}
|
|
8057
|
+
.motion-safe\:animate-spin{
|
|
8058
|
+
animation: spin 1s linear infinite;
|
|
8059
|
+
}
|
|
8060
|
+
}
|
|
8061
|
+
|
|
8062
|
+
.dark\:divide-gray-700:is(.dark *) > :not([hidden]) ~ :not([hidden]){
|
|
8063
|
+
border-color: var(--gray-700);
|
|
7983
8064
|
}
|
|
7984
8065
|
|
|
7985
8066
|
.dark\:border:is(.dark *){
|
|
@@ -8019,6 +8100,10 @@ video {
|
|
|
8019
8100
|
border-color: var(--primary);
|
|
8020
8101
|
}
|
|
8021
8102
|
|
|
8103
|
+
.dark\:border-red-500\/20:is(.dark *){
|
|
8104
|
+
border-color: rgb(239 68 68 / 0.2);
|
|
8105
|
+
}
|
|
8106
|
+
|
|
8022
8107
|
.dark\:border-transparent:is(.dark *){
|
|
8023
8108
|
border-color: transparent;
|
|
8024
8109
|
}
|
|
@@ -8166,6 +8251,14 @@ video {
|
|
|
8166
8251
|
background-color: rgb(254 202 202 / var(--tw-bg-opacity, 1));
|
|
8167
8252
|
}
|
|
8168
8253
|
|
|
8254
|
+
.dark\:bg-red-500\/10:is(.dark *){
|
|
8255
|
+
background-color: rgb(239 68 68 / 0.1);
|
|
8256
|
+
}
|
|
8257
|
+
|
|
8258
|
+
.dark\:bg-red-500\/15:is(.dark *){
|
|
8259
|
+
background-color: rgb(239 68 68 / 0.15);
|
|
8260
|
+
}
|
|
8261
|
+
|
|
8169
8262
|
.dark\:bg-red-500\/20:is(.dark *){
|
|
8170
8263
|
background-color: rgb(239 68 68 / 0.2);
|
|
8171
8264
|
}
|
|
@@ -8274,6 +8367,11 @@ video {
|
|
|
8274
8367
|
color: rgb(254 243 199 / var(--tw-text-opacity, 1));
|
|
8275
8368
|
}
|
|
8276
8369
|
|
|
8370
|
+
.dark\:text-amber-400:is(.dark *){
|
|
8371
|
+
--tw-text-opacity: 1;
|
|
8372
|
+
color: rgb(251 191 36 / var(--tw-text-opacity, 1));
|
|
8373
|
+
}
|
|
8374
|
+
|
|
8277
8375
|
.dark\:text-black:is(.dark *){
|
|
8278
8376
|
--tw-text-opacity: 1;
|
|
8279
8377
|
color: rgb(0 0 0 / var(--tw-text-opacity, 1));
|
|
@@ -8284,11 +8382,21 @@ video {
|
|
|
8284
8382
|
color: rgb(219 234 254 / var(--tw-text-opacity, 1));
|
|
8285
8383
|
}
|
|
8286
8384
|
|
|
8385
|
+
.dark\:text-blue-400:is(.dark *){
|
|
8386
|
+
--tw-text-opacity: 1;
|
|
8387
|
+
color: rgb(96 165 250 / var(--tw-text-opacity, 1));
|
|
8388
|
+
}
|
|
8389
|
+
|
|
8287
8390
|
.dark\:text-emerald-100:is(.dark *){
|
|
8288
8391
|
--tw-text-opacity: 1;
|
|
8289
8392
|
color: rgb(209 250 229 / var(--tw-text-opacity, 1));
|
|
8290
8393
|
}
|
|
8291
8394
|
|
|
8395
|
+
.dark\:text-emerald-400:is(.dark *){
|
|
8396
|
+
--tw-text-opacity: 1;
|
|
8397
|
+
color: rgb(52 211 153 / var(--tw-text-opacity, 1));
|
|
8398
|
+
}
|
|
8399
|
+
|
|
8292
8400
|
.dark\:text-fuchsia-400:is(.dark *){
|
|
8293
8401
|
--tw-text-opacity: 1;
|
|
8294
8402
|
color: rgb(232 121 249 / var(--tw-text-opacity, 1));
|
|
@@ -8314,6 +8422,10 @@ video {
|
|
|
8314
8422
|
color: var(--gray-50);
|
|
8315
8423
|
}
|
|
8316
8424
|
|
|
8425
|
+
.dark\:text-gray-500:is(.dark *){
|
|
8426
|
+
color: var(--gray-500);
|
|
8427
|
+
}
|
|
8428
|
+
|
|
8317
8429
|
.dark\:text-gray-900:is(.dark *){
|
|
8318
8430
|
color: var(--gray-900);
|
|
8319
8431
|
}
|
|
@@ -8351,6 +8463,15 @@ video {
|
|
|
8351
8463
|
color: rgb(254 226 226 / var(--tw-text-opacity, 1));
|
|
8352
8464
|
}
|
|
8353
8465
|
|
|
8466
|
+
.dark\:text-red-300\/90:is(.dark *){
|
|
8467
|
+
color: rgb(252 165 165 / 0.9);
|
|
8468
|
+
}
|
|
8469
|
+
|
|
8470
|
+
.dark\:text-red-400:is(.dark *){
|
|
8471
|
+
--tw-text-opacity: 1;
|
|
8472
|
+
color: rgb(248 113 113 / var(--tw-text-opacity, 1));
|
|
8473
|
+
}
|
|
8474
|
+
|
|
8354
8475
|
.dark\:text-slate-400:is(.dark *){
|
|
8355
8476
|
--tw-text-opacity: 1;
|
|
8356
8477
|
color: rgb(148 163 184 / var(--tw-text-opacity, 1));
|
|
@@ -8379,6 +8500,10 @@ video {
|
|
|
8379
8500
|
--tw-ring-color: var(--primary);
|
|
8380
8501
|
}
|
|
8381
8502
|
|
|
8503
|
+
.dark\:hover\:border-gray-600:hover:is(.dark *){
|
|
8504
|
+
border-color: var(--gray-600);
|
|
8505
|
+
}
|
|
8506
|
+
|
|
8382
8507
|
.dark\:hover\:border-primary:hover:is(.dark *){
|
|
8383
8508
|
border-color: var(--primary);
|
|
8384
8509
|
}
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
import { HiX } from 'react-icons/hi'
|
|
9
9
|
import ChatView from '@/views/concepts/ai/Chat/components/ChatView'
|
|
10
10
|
import ChatHistoryRenameDialog from '@/views/concepts/ai/Chat/components/ChatHistoryRenameDialog'
|
|
11
|
-
import ModelSelect from '@/views/concepts/ai/Chat/components/ModelSelect'
|
|
12
11
|
import useResizablePanel from './useResizablePanel'
|
|
13
12
|
import ResizeHandles from './ResizeHandles'
|
|
14
13
|
|
|
@@ -71,7 +70,6 @@ const OrbeAiWidget = () => {
|
|
|
71
70
|
</span>
|
|
72
71
|
</div>
|
|
73
72
|
<div className="flex items-center gap-2">
|
|
74
|
-
<ModelSelect />
|
|
75
73
|
<button
|
|
76
74
|
type="button"
|
|
77
75
|
className={iconButtonClass}
|
|
@@ -34,6 +34,7 @@ const ChatBox = forwardRef<ScrollBarRef, ChatBoxProps>((props, ref) => {
|
|
|
34
34
|
bubbleClass,
|
|
35
35
|
myBubbleClass,
|
|
36
36
|
botBubbleClass,
|
|
37
|
+
errorBubbleClass,
|
|
37
38
|
renderTyping,
|
|
38
39
|
typing,
|
|
39
40
|
messageListClass,
|
|
@@ -64,6 +65,7 @@ const ChatBox = forwardRef<ScrollBarRef, ChatBoxProps>((props, ref) => {
|
|
|
64
65
|
bubbleClass={bubbleClass}
|
|
65
66
|
myBubbleClass={myBubbleClass}
|
|
66
67
|
botBubbleClass={botBubbleClass}
|
|
68
|
+
errorBubbleClass={errorBubbleClass}
|
|
67
69
|
renderTyping={renderTyping}
|
|
68
70
|
/> )}
|
|
69
71
|
{children}
|
|
@@ -6,7 +6,7 @@ import { forwardRef } from 'react'
|
|
|
6
6
|
import type { ScrollBarRef } from '@/components/ui/ScrollBar'
|
|
7
7
|
import type { MessageProps } from './Message'
|
|
8
8
|
|
|
9
|
-
type List = MessageProps & { fresh?: boolean }
|
|
9
|
+
type List = MessageProps & { fresh?: boolean; isError?: boolean }
|
|
10
10
|
|
|
11
11
|
export type MessageListProps = {
|
|
12
12
|
list: List[]
|
|
@@ -24,6 +24,7 @@ export type MessageListProps = {
|
|
|
24
24
|
bubbleClass?: string
|
|
25
25
|
myBubbleClass?: string
|
|
26
26
|
botBubbleClass?: string
|
|
27
|
+
errorBubbleClass?: string
|
|
27
28
|
renderTyping?: () => ReactNode
|
|
28
29
|
messageListClass?: string
|
|
29
30
|
}
|
|
@@ -39,6 +40,7 @@ const MessageList = forwardRef<ScrollBarRef, MessageListProps>((props, ref) => {
|
|
|
39
40
|
bubbleClass,
|
|
40
41
|
myBubbleClass,
|
|
41
42
|
botBubbleClass,
|
|
43
|
+
errorBubbleClass,
|
|
42
44
|
renderTyping,
|
|
43
45
|
} = props
|
|
44
46
|
|
|
@@ -56,9 +58,11 @@ const MessageList = forwardRef<ScrollBarRef, MessageListProps>((props, ref) => {
|
|
|
56
58
|
showAvatar={showAvatar}
|
|
57
59
|
avatarGap={avatarGap}
|
|
58
60
|
bubbleClass={
|
|
59
|
-
message.
|
|
60
|
-
?
|
|
61
|
-
:
|
|
61
|
+
message.isError
|
|
62
|
+
? errorBubbleClass ?? bubbleClass
|
|
63
|
+
: message.isMyMessage
|
|
64
|
+
? myBubbleClass ?? bubbleClass
|
|
65
|
+
: botBubbleClass ?? bubbleClass
|
|
62
66
|
}
|
|
63
67
|
{...message}
|
|
64
68
|
{...(customRenderer
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
+
import { authHeaders } from './aiAuthHeaders'
|
|
1
2
|
import ApiService from './ApiService'
|
|
2
|
-
import {
|
|
3
|
+
import { readSse } from './sseParser'
|
|
4
|
+
import type { ChatEvent } from '@/views/concepts/ai/Chat/types'
|
|
3
5
|
import type { AxiosRequestConfig } from 'axios'
|
|
4
6
|
|
|
5
|
-
/** Informa ao backend qual modelo usar. Sem o header, ele aplica o default. */
|
|
6
|
-
export const AI_MODEL_HEADER = 'X-Ai-Model'
|
|
7
|
-
|
|
8
7
|
const AI_DEV_URL = 'http://localhost:8000'
|
|
9
8
|
const AI_BUILD_URL = 'https://orbe-ai-homolog.apps.qas.orbeagro.com.br'
|
|
10
9
|
|
|
@@ -30,29 +29,6 @@ function getAiApiUrl() {
|
|
|
30
29
|
|
|
31
30
|
export const AI_API_URL = getAiApiUrl()
|
|
32
31
|
|
|
33
|
-
export type AiModel = {
|
|
34
|
-
id: string
|
|
35
|
-
label: string
|
|
36
|
-
default: boolean
|
|
37
|
-
cloud: boolean
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export type GetAiModelsResponse = {
|
|
41
|
-
models: AiModel[]
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Header do modelo escolhido, montado por chamada.
|
|
46
|
-
*
|
|
47
|
-
* Deliberadamente NAO e um interceptor global do AxiosBase: o chat vive no
|
|
48
|
-
* layout de todos os MFEs, e um interceptor faria toda requisicao de todo
|
|
49
|
-
* modulo passar por essa checagem so para servir ao /ai/*.
|
|
50
|
-
*/
|
|
51
|
-
const aiModelHeader = () => {
|
|
52
|
-
const selectedModel = useAiModelStore.getState().selectedModel
|
|
53
|
-
return selectedModel ? { [AI_MODEL_HEADER]: selectedModel } : undefined
|
|
54
|
-
}
|
|
55
|
-
|
|
56
32
|
/**
|
|
57
33
|
* Toda chamada de IA sai pelo AI_API_URL (o baseURL por requisicao vence o da
|
|
58
34
|
* instancia do AxiosBase) e fica fora do loading global — o chat mostra o
|
|
@@ -65,29 +41,98 @@ const aiRequest = <T>(config: AxiosRequestConfig) =>
|
|
|
65
41
|
skipGlobalLoading: true,
|
|
66
42
|
})
|
|
67
43
|
|
|
68
|
-
export async function
|
|
69
|
-
prompt: string
|
|
70
|
-
attachments?: File[]
|
|
71
|
-
}) {
|
|
72
|
-
return aiRequest<T>({
|
|
73
|
-
url: '/ai/chat',
|
|
74
|
-
method: 'post',
|
|
75
|
-
data,
|
|
76
|
-
headers: aiModelHeader(),
|
|
77
|
-
})
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export async function apiGetChatHistory<T>() {
|
|
44
|
+
export async function apiGetChatHistory<T>(conversationId?: string) {
|
|
81
45
|
return aiRequest<T>({
|
|
82
46
|
url: '/ai/chat/history',
|
|
83
47
|
method: 'get',
|
|
48
|
+
params: conversationId ? { conversation_id: conversationId } : undefined,
|
|
84
49
|
})
|
|
85
50
|
}
|
|
86
51
|
|
|
87
|
-
export
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
52
|
+
export type StreamChatParams = {
|
|
53
|
+
prompt: string
|
|
54
|
+
/** Identifica a conversa; o backend usa como thread da memoria. */
|
|
55
|
+
conversationId?: string
|
|
56
|
+
signal?: AbortSignal
|
|
57
|
+
onEvent: (evento: ChatEvent) => void
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type ResumeChatParams = {
|
|
61
|
+
/** true = aprovar a operacao pendente, false = negar. */
|
|
62
|
+
approved: boolean
|
|
63
|
+
conversationId?: string
|
|
64
|
+
signal?: AbortSignal
|
|
65
|
+
onEvent: (evento: ChatEvent) => void
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Envia a mensagem e consome a resposta em streaming (SSE).
|
|
70
|
+
*
|
|
71
|
+
* Usa `fetch`, e nao o Axios, porque o Axios no browser so resolve a Promise
|
|
72
|
+
* com a resposta inteira — nao ha como ler o corpo enquanto ele chega.
|
|
73
|
+
*/
|
|
74
|
+
export async function streamChat({
|
|
75
|
+
prompt,
|
|
76
|
+
conversationId,
|
|
77
|
+
signal,
|
|
78
|
+
onEvent,
|
|
79
|
+
}: StreamChatParams): Promise<void> {
|
|
80
|
+
await postarEConsumir(
|
|
81
|
+
'/ai/chat/stream',
|
|
82
|
+
{ prompt, conversation_id: conversationId },
|
|
83
|
+
onEvent,
|
|
84
|
+
signal,
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Retoma uma conversa parada num pedido de aprovacao.
|
|
90
|
+
*
|
|
91
|
+
* Devolve o mesmo tipo de stream do `streamChat`, e a resposta continua na
|
|
92
|
+
* MESMA mensagem do chat — o backend so volta do ponto onde parou.
|
|
93
|
+
*/
|
|
94
|
+
export async function resumeChat({
|
|
95
|
+
approved,
|
|
96
|
+
conversationId,
|
|
97
|
+
signal,
|
|
98
|
+
onEvent,
|
|
99
|
+
}: ResumeChatParams): Promise<void> {
|
|
100
|
+
await postarEConsumir(
|
|
101
|
+
'/ai/chat/resume',
|
|
102
|
+
{ approved, conversation_id: conversationId },
|
|
103
|
+
onEvent,
|
|
104
|
+
signal,
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** POST + leitura do SSE, comum ao envio e a retomada. */
|
|
109
|
+
async function postarEConsumir(
|
|
110
|
+
caminho: string,
|
|
111
|
+
corpo: Record<string, unknown>,
|
|
112
|
+
onEvent: (evento: ChatEvent) => void,
|
|
113
|
+
signal?: AbortSignal,
|
|
114
|
+
): Promise<void> {
|
|
115
|
+
const resposta = await fetch(`${AI_API_URL}${caminho}`, {
|
|
116
|
+
method: 'POST',
|
|
117
|
+
headers: {
|
|
118
|
+
...authHeaders(),
|
|
119
|
+
'Content-Type': 'application/json',
|
|
120
|
+
},
|
|
121
|
+
body: JSON.stringify(corpo),
|
|
122
|
+
signal,
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
if (!resposta.ok || !resposta.body) {
|
|
126
|
+
throw new Error(`Falha ao falar com a IA (HTTP ${resposta.status})`)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
await readSse(resposta.body, ({ event, data }) => {
|
|
130
|
+
try {
|
|
131
|
+
onEvent({ type: event, data: JSON.parse(data) } as ChatEvent)
|
|
132
|
+
} catch (error) {
|
|
133
|
+
// Evento malformado nao pode derrubar o stream inteiro.
|
|
134
|
+
console.debug('Evento SSE ignorado:', event, error)
|
|
135
|
+
}
|
|
91
136
|
})
|
|
92
137
|
}
|
|
93
138
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import appConfig from '@/configs/app.config'
|
|
2
|
+
import {
|
|
3
|
+
REQUEST_HEADER_AUTH_KEY,
|
|
4
|
+
TOKEN_NAME_IN_STORAGE,
|
|
5
|
+
TOKEN_TYPE,
|
|
6
|
+
} from '@/constants/api.constant'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Headers de autenticacao lidos do storage.
|
|
10
|
+
*
|
|
11
|
+
* Existe porque o chat de IA usa `fetch` (o Axios nao faz streaming no
|
|
12
|
+
* browser) e portanto nao passa pelo interceptor. Em vez de duplicar as regras
|
|
13
|
+
* de onde mora o token, o interceptor e o fetch chamam esta funcao — uma
|
|
14
|
+
* verdade so.
|
|
15
|
+
*
|
|
16
|
+
* Ver AxiosRequestIntrceptorConfigCallback, que a consome.
|
|
17
|
+
*/
|
|
18
|
+
export const authHeaders = (): Record<string, string> => {
|
|
19
|
+
const storage = appConfig.accessTokenPersistStrategy
|
|
20
|
+
const headers: Record<string, string> = {}
|
|
21
|
+
|
|
22
|
+
if (storage !== 'localStorage' && storage !== 'sessionStorage') {
|
|
23
|
+
return headers
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const source = storage === 'localStorage' ? localStorage : sessionStorage
|
|
27
|
+
const accessToken = source.getItem(TOKEN_NAME_IN_STORAGE) || ''
|
|
28
|
+
|
|
29
|
+
if (accessToken) {
|
|
30
|
+
headers[REQUEST_HEADER_AUTH_KEY] = `${TOKEN_TYPE}${accessToken}`
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const userId = readUserId()
|
|
34
|
+
if (userId) {
|
|
35
|
+
headers['X-User-Id'] = userId
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return headers
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* userId da sessao persistida pelo zustand.
|
|
43
|
+
*
|
|
44
|
+
* Silencioso em caso de erro: um storage corrompido nao pode derrubar a
|
|
45
|
+
* requisicao — sem o header, o backend apenas trata o usuario como desconhecido.
|
|
46
|
+
*/
|
|
47
|
+
const readUserId = (): string | undefined => {
|
|
48
|
+
try {
|
|
49
|
+
const raw = localStorage.getItem('SessionUserPageStore')
|
|
50
|
+
if (!raw) {
|
|
51
|
+
return undefined
|
|
52
|
+
}
|
|
53
|
+
return JSON.parse(raw)?.state?.user?.userId
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.debug('Could not read userId from session store:', error)
|
|
56
|
+
return undefined
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -1,47 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
TOKEN_TYPE,
|
|
4
|
-
REQUEST_HEADER_AUTH_KEY,
|
|
5
|
-
TOKEN_NAME_IN_STORAGE,
|
|
6
|
-
} from '@/constants/api.constant'
|
|
1
|
+
import { authHeaders } from '../aiAuthHeaders'
|
|
7
2
|
import type { InternalAxiosRequestConfig } from 'axios'
|
|
8
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Injeta Authorization e X-User-Id em toda requisicao do Axios.
|
|
6
|
+
*
|
|
7
|
+
* As regras de onde o token mora vivem em `authHeaders` — compartilhadas com o
|
|
8
|
+
* chat de IA, que usa `fetch` e nao passa por aqui.
|
|
9
|
+
*/
|
|
9
10
|
const AxiosRequestIntrceptorConfigCallback = (
|
|
10
11
|
config: InternalAxiosRequestConfig,
|
|
11
12
|
) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
let accessToken = ''
|
|
16
|
-
|
|
17
|
-
if (storage === 'localStorage') {
|
|
18
|
-
accessToken = localStorage.getItem(TOKEN_NAME_IN_STORAGE) || ''
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (storage === 'sessionStorage') {
|
|
22
|
-
accessToken = sessionStorage.getItem(TOKEN_NAME_IN_STORAGE) || ''
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (accessToken) {
|
|
26
|
-
config.headers[REQUEST_HEADER_AUTH_KEY] =
|
|
27
|
-
`${TOKEN_TYPE}${accessToken}`
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Adicionar X-User-Id header se o usuário estiver autenticado
|
|
31
|
-
try {
|
|
32
|
-
const sessionUserStore = localStorage.getItem('SessionUserPageStore')
|
|
33
|
-
if (sessionUserStore) {
|
|
34
|
-
const parsedStore = JSON.parse(sessionUserStore)
|
|
35
|
-
const userId = parsedStore?.state?.user?.userId
|
|
36
|
-
if (userId) {
|
|
37
|
-
config.headers['X-User-Id'] = userId
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
} catch (error) {
|
|
41
|
-
// Silently ignore errors reading user session
|
|
42
|
-
console.debug('Could not read userId from session store:', error)
|
|
43
|
-
}
|
|
44
|
-
}
|
|
13
|
+
Object.entries(authHeaders()).forEach(([chave, valor]) => {
|
|
14
|
+
config.headers[chave] = valor
|
|
15
|
+
})
|
|
45
16
|
|
|
46
17
|
return config
|
|
47
18
|
}
|