IO4IT 4.0.25__tar.gz → 4.0.26__tar.gz
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.
- {io4it-4.0.25 → io4it-4.0.26}/PKG-INFO +1 -1
- {io4it-4.0.25 → io4it-4.0.26}/io4it.egg-info/PKG-INFO +1 -1
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/custom_api.py +84 -43
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWCustomLLMApi.py +15 -3
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWExportMarkdown.py +2 -2
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWProcessPoolExecutor.py +44 -21
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owprocesspoolexecutor.ui +17 -30
- {io4it-4.0.25 → io4it-4.0.26}/setup.py +1 -1
- {io4it-4.0.25 → io4it-4.0.26}/io4it.egg-info/SOURCES.txt +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/io4it.egg-info/dependency_links.txt +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/io4it.egg-info/entry_points.txt +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/io4it.egg-info/namespace_packages.txt +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/io4it.egg-info/requires.txt +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/io4it.egg-info/top_level.txt +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/__init__.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/ocr_function/__init__.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/ocr_function/word_converter.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/toolViews/designer/key_manager_ui.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/toolViews/designer/link_workflow_manager_ui.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/toolViews/key_manager_ui.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/toolViews/linkHTLMWorkflow_manager_ui.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/__init__.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/environment_collector.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/file2images.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/keys_manager.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/mail.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/pool_exec_utils.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/pst_extractor/TigerODMPST.dll +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/pst_extractor/__init__.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/pst_extractor/export_pst.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/pst_extractor/libpff.dll +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/pst_extractor/z.dll +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/secret_manager.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/utils/utils_md.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWChatGpt.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWDeep_Search.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWDoclingToMarkdown.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWExtractTablesDocxToXlsx.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWInboxMailMonitoring.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWJsonToDataTable.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWMD2HTML.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWMarkdownLoader.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWMarkdownizer.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWOfficeNormalizer.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWPPTX2JPG.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWParserHTML.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWPdfType.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWPipAuditor.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWS3Uploader.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWS3downloader.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWS3list.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWWebSearch.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWXLSX_insert.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWmailLoader.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWmailSender.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/OWwordpdf2docx.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/__init__.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/__init__.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/nogui.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/ow_extract_tables_docx_to_xlsx.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/ow_file_ext_selector.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/ow_json_to_data_table.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owchatgpt.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owcustomllmapi.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owdeepsearch.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owdoclingtomarkdown.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owexportmarkdown.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owfile2images.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owinboxmailmonitoring.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owinsertdatatoexcel.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owmailloader.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owmailsender.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owmarkdownizer.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owmarkdownloader.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owmd2html.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owofficenormalizer.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owparserhtml.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owpdftype.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owpipauditor.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owspeechtotext.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owvisualizationer.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/owwebsearch.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/wordpdf2docx.ui +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/__init__.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/chatgpt.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/check_pdf.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/deepsearch.svg +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/dep_md_old.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/download.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/export_md.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/extract_table.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/file2images.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/file_extensor.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/html.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/json-file.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/list_aws.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/load_md.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/mail_loader.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/mail_writer.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/md.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/monitor-email.svg +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/office_normalizer.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/owcustomllmapi.svg +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/owmd2html.svg +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/pip_auditor.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/process_pool_executor.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/speech_to_text.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/upload.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/visualizationer.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/websearch.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/wordpdf2docx.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons/xlsx_insert.png +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/icons_dev/__init__.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/orangecontrib/__init__.py +0 -0
- {io4it-4.0.25 → io4it-4.0.26}/setup.cfg +0 -0
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import base64
|
|
2
|
-
import mimetypes
|
|
3
1
|
import os
|
|
2
|
+
import re
|
|
3
|
+
import json
|
|
4
|
+
import copy
|
|
5
|
+
import numpy as np
|
|
4
6
|
|
|
5
7
|
import requests
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
from Orange.data import StringVariable, Table
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
13
|
+
from Orange.widgets.orangecontrib.AAIT.llm.answers_llama import write_tokens_to_file, prompt_to_messages, conv_to_messages
|
|
14
|
+
else:
|
|
15
|
+
from orangecontrib.AAIT.llm.answers_llama import write_tokens_to_file, prompt_to_messages, conv_to_messages
|
|
9
16
|
|
|
10
17
|
|
|
11
18
|
def build_headers(header_name, auth_scheme, api_key):
|
|
@@ -15,37 +22,25 @@ def build_headers(header_name, auth_scheme, api_key):
|
|
|
15
22
|
return {"Content-Type": "application/json", header_name: value}
|
|
16
23
|
|
|
17
24
|
|
|
18
|
-
def
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
mime_type = mime_type or "application/octet-stream"
|
|
22
|
-
with open(file_path, "rb") as f:
|
|
23
|
-
encoded = base64.b64encode(f.read()).decode("utf-8")
|
|
24
|
-
return f"data:{mime_type};base64,{encoded}"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def build_user_content(prompt, image_paths):
|
|
28
|
-
"""Build the 'content' field of a user message, attaching images when provided."""
|
|
29
|
-
if not image_paths:
|
|
30
|
-
return str(prompt)
|
|
31
|
-
|
|
32
|
-
content = []
|
|
33
|
-
for image_path in image_paths:
|
|
34
|
-
image_path = image_path.strip().strip("'").strip('"')
|
|
35
|
-
if not image_path:
|
|
36
|
-
continue
|
|
37
|
-
if not os.path.exists(image_path):
|
|
38
|
-
content.append({"type": "text", "text": f"[ERROR] Image not found: {image_path}"})
|
|
39
|
-
continue
|
|
40
|
-
try:
|
|
41
|
-
content.append({"type": "image_url", "image_url": {"url": image_to_data_uri(image_path)}})
|
|
42
|
-
except Exception as e:
|
|
43
|
-
content.append({"type": "text", "text": f"[ERROR] Unable to read image {image_path}: {e}"})
|
|
44
|
-
content.append({"type": "text", "text": str(prompt)})
|
|
45
|
-
return content
|
|
25
|
+
def search_for_streamed_token(decoded_line):
|
|
26
|
+
r"""
|
|
27
|
+
/!\ This function is meant to be updated whenever a new response format is identified /!\
|
|
46
28
|
|
|
47
|
-
|
|
48
|
-
|
|
29
|
+
Parse a decoded stream response "line" to find the token generated by a LLM.
|
|
30
|
+
"""
|
|
31
|
+
known_keys = ["content", "reasoning"]
|
|
32
|
+
dict_regex = r"\{[\s\S]*\}"
|
|
33
|
+
match = re.search(dict_regex, decoded_line)
|
|
34
|
+
if not match:
|
|
35
|
+
return "Token not found"
|
|
36
|
+
|
|
37
|
+
json_data = json.loads(match.group())
|
|
38
|
+
delta = json_data["choices"][0]["delta"]
|
|
39
|
+
token = next((delta[key] for key in known_keys if key in delta), "Token not found")
|
|
40
|
+
return token
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def call_chat_completion(messages, config, stream=False, workflow_id="Request_RAG"):
|
|
49
44
|
"""
|
|
50
45
|
Call a /chat/completions endpoint using the widely adopted chat-completions
|
|
51
46
|
message format. Vision-capable models can be reached by passing image_paths,
|
|
@@ -58,11 +53,6 @@ def call_chat_completion(prompt, system_prompt, config, image_paths=None):
|
|
|
58
53
|
url = config["base_url"].rstrip("/") + config["route"]
|
|
59
54
|
headers = build_headers(config["header_name"], config["auth_scheme"], config["api_key"])
|
|
60
55
|
|
|
61
|
-
messages = []
|
|
62
|
-
if system_prompt:
|
|
63
|
-
messages.append({"role": "system", "content": str(system_prompt)})
|
|
64
|
-
messages.append({"role": "user", "content": build_user_content(prompt, image_paths)})
|
|
65
|
-
|
|
66
56
|
payload = {
|
|
67
57
|
"model": config["model"],
|
|
68
58
|
"messages": messages,
|
|
@@ -86,10 +76,25 @@ def call_chat_completion(prompt, system_prompt, config, image_paths=None):
|
|
|
86
76
|
proxy_url = config.get("proxy_url") or ""
|
|
87
77
|
kwargs["proxies"] = {"http": proxy_url, "https": proxy_url}
|
|
88
78
|
|
|
89
|
-
response = requests.post(url, headers=headers, json=payload, **kwargs)
|
|
79
|
+
response = requests.post(url, headers=headers, json=payload, stream=stream, **kwargs)
|
|
90
80
|
response.raise_for_status()
|
|
91
|
-
|
|
92
|
-
|
|
81
|
+
|
|
82
|
+
if not stream:
|
|
83
|
+
data = response.json()
|
|
84
|
+
return data["choices"][0]["message"]["content"]
|
|
85
|
+
else:
|
|
86
|
+
answer = ""
|
|
87
|
+
for line in response.iter_lines():
|
|
88
|
+
if line:
|
|
89
|
+
decoded_line = line.decode("utf-8")
|
|
90
|
+
try:
|
|
91
|
+
token = search_for_streamed_token(decoded_line)
|
|
92
|
+
except Exception as e:
|
|
93
|
+
token = "Error"
|
|
94
|
+
print("An error occured when trying to get token from stream response:", e)
|
|
95
|
+
answer += token
|
|
96
|
+
write_tokens_to_file(token, workflow_id=workflow_id)
|
|
97
|
+
return answer
|
|
93
98
|
|
|
94
99
|
|
|
95
100
|
def generate_answers(data, config, progress_callback=None):
|
|
@@ -116,8 +121,9 @@ def generate_answers(data, config, progress_callback=None):
|
|
|
116
121
|
prompt = prompts[i]
|
|
117
122
|
system_prompt = system_prompts[i] if system_prompts is not None else None
|
|
118
123
|
image_paths = image_paths_column[i].split(";") if image_paths_column is not None else None
|
|
124
|
+
messages = prompt_to_messages(prompt, system_prompt, image_paths)
|
|
119
125
|
try:
|
|
120
|
-
answer = call_chat_completion(
|
|
126
|
+
answer = call_chat_completion(messages, config, stream=True)
|
|
121
127
|
except requests.HTTPError as e:
|
|
122
128
|
body = e.response.text if e.response is not None else str(e)
|
|
123
129
|
answer = f"[ERROR] HTTP {e.response.status_code if e.response is not None else '?'}: {body}"
|
|
@@ -130,3 +136,38 @@ def generate_answers(data, config, progress_callback=None):
|
|
|
130
136
|
|
|
131
137
|
answer_var = StringVariable("Answer")
|
|
132
138
|
return data.add_column(answer_var, answers)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def continue_conversation(table, config, progress_callback=None):
|
|
143
|
+
"""
|
|
144
|
+
Runs call_chat_completion considering the table as a conversation (list of messages).
|
|
145
|
+
"""
|
|
146
|
+
data = copy.deepcopy(table)
|
|
147
|
+
messages = conv_to_messages(data)
|
|
148
|
+
if not messages:
|
|
149
|
+
return data
|
|
150
|
+
|
|
151
|
+
try:
|
|
152
|
+
answer = call_chat_completion(messages, config, stream=True)
|
|
153
|
+
except requests.HTTPError as e:
|
|
154
|
+
body = e.response.text if e.response is not None else str(e)
|
|
155
|
+
answer = f"[ERROR] HTTP {e.response.status_code if e.response is not None else '?'}: {body}"
|
|
156
|
+
except Exception as e:
|
|
157
|
+
answer = f"[ERROR] {e}"
|
|
158
|
+
|
|
159
|
+
# Create output table
|
|
160
|
+
meta = data.metas[-1].copy()
|
|
161
|
+
meta_names = [m.name for m in data.domain.metas]
|
|
162
|
+
meta[meta_names.index("role")] = "assistant"
|
|
163
|
+
meta[meta_names.index("type")] = "text"
|
|
164
|
+
meta[meta_names.index("content")] = answer
|
|
165
|
+
empty_x = np.zeros((1, len(data.domain.attributes)))
|
|
166
|
+
|
|
167
|
+
new_row = Table.from_numpy(
|
|
168
|
+
data.domain,
|
|
169
|
+
X=empty_x,
|
|
170
|
+
metas=np.array([meta], dtype=object)
|
|
171
|
+
)
|
|
172
|
+
out_data = Table.concatenate([data, new_row])
|
|
173
|
+
return out_data
|
|
@@ -13,11 +13,13 @@ from AnyQt.QtWidgets import (
|
|
|
13
13
|
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
14
14
|
from Orange.widgets.orangecontrib.IO4IT.utils import custom_api
|
|
15
15
|
from Orange.widgets.orangecontrib.AAIT.utils import thread_management
|
|
16
|
+
from Orange.widgets.orangecontrib.AAIT.llm.answers_llama import identify_table_type
|
|
16
17
|
from Orange.widgets.orangecontrib.AAIT.utils.import_uic import uic
|
|
17
18
|
from Orange.widgets.orangecontrib.AAIT.utils.initialize_from_ini import apply_modification_from_python_file
|
|
18
19
|
else:
|
|
19
20
|
from orangecontrib.IO4IT.utils import custom_api
|
|
20
21
|
from orangecontrib.AAIT.utils import thread_management
|
|
22
|
+
from orangecontrib.AAIT.llm.answers_llama import identify_table_type
|
|
21
23
|
from orangecontrib.AAIT.utils.import_uic import uic
|
|
22
24
|
from orangecontrib.AAIT.utils.initialize_from_ini import apply_modification_from_python_file
|
|
23
25
|
|
|
@@ -192,8 +194,14 @@ class OWCustomLLMApi(widget.OWWidget):
|
|
|
192
194
|
if self.data is None:
|
|
193
195
|
self.Outputs.data.send(None)
|
|
194
196
|
return
|
|
195
|
-
|
|
196
|
-
|
|
197
|
+
|
|
198
|
+
table_type = identify_table_type(self.data)
|
|
199
|
+
if table_type == "error":
|
|
200
|
+
self.error("The table must contain either (StringVariable):\n- role + type + content\nor:\n- prompt (image paths)")
|
|
201
|
+
self.Outputs.data.send(None)
|
|
202
|
+
return
|
|
203
|
+
elif table_type == "multiple":
|
|
204
|
+
self.error("Cannot have role/type/content and prompt simultaneously.")
|
|
197
205
|
self.Outputs.data.send(None)
|
|
198
206
|
return
|
|
199
207
|
|
|
@@ -213,7 +221,11 @@ class OWCustomLLMApi(widget.OWWidget):
|
|
|
213
221
|
self.progressBarInit()
|
|
214
222
|
self.textBrowser.setText("")
|
|
215
223
|
|
|
216
|
-
|
|
224
|
+
|
|
225
|
+
if table_type == "batch":
|
|
226
|
+
self.thread = thread_management.Thread(custom_api.generate_answers, self.data, self.build_config())
|
|
227
|
+
elif table_type == "conversation":
|
|
228
|
+
self.thread = thread_management.Thread(custom_api.continue_conversation, self.data, self.build_config())
|
|
217
229
|
self.thread.progress.connect(self.handle_progress)
|
|
218
230
|
self.thread.result.connect(self.handle_result)
|
|
219
231
|
self.thread.finish.connect(self.handle_finish)
|
|
@@ -265,8 +265,8 @@ class OWExportMarkdown(widget.OWWidget):
|
|
|
265
265
|
)
|
|
266
266
|
self.ajouter_entete_pied_pptx(
|
|
267
267
|
pptx_out,
|
|
268
|
-
"
|
|
269
|
-
"Page générée automatiquement"
|
|
268
|
+
"TigerODM – Présentation",
|
|
269
|
+
"Page générée automatiquement par IA"
|
|
270
270
|
)
|
|
271
271
|
produced_pptx = pptx_out if os.path.isfile(pptx_out) else ""
|
|
272
272
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import sys
|
|
3
|
-
from AnyQt.QtWidgets import QSpinBox, QLabel, QPushButton, QGroupBox, QCheckBox
|
|
3
|
+
from AnyQt.QtWidgets import QSpinBox, QLabel, QPushButton, QGroupBox, QCheckBox, QApplication
|
|
4
|
+
from AnyQt.QtCore import QTimer
|
|
4
5
|
from Orange.widgets import widget
|
|
5
6
|
from Orange.widgets.utils.signals import Output
|
|
6
7
|
from Orange.widgets.settings import Setting
|
|
@@ -8,9 +9,11 @@ from Orange.widgets.settings import Setting
|
|
|
8
9
|
if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
|
|
9
10
|
from Orange.widgets.orangecontrib.IO4IT.utils import pool_exec_utils
|
|
10
11
|
from Orange.widgets.orangecontrib.AAIT.utils.import_uic import uic
|
|
12
|
+
from Orange.widgets.orangecontrib.AAIT.utils import help_management
|
|
11
13
|
else:
|
|
12
14
|
from orangecontrib.IO4IT.utils import pool_exec_utils
|
|
13
15
|
from orangecontrib.AAIT.utils.import_uic import uic
|
|
16
|
+
from orangecontrib.AAIT.utils import help_management
|
|
14
17
|
|
|
15
18
|
|
|
16
19
|
class OWProcessPoolExecutor(widget.OWWidget):
|
|
@@ -24,7 +27,8 @@ class OWProcessPoolExecutor(widget.OWWidget):
|
|
|
24
27
|
want_control_area = False
|
|
25
28
|
priority = 900
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
str_workers: str = Setting("4")
|
|
31
|
+
str_autosend: str = Setting("False")
|
|
28
32
|
|
|
29
33
|
class Outputs:
|
|
30
34
|
executor = Output("ProcessPoolExecutor", object)
|
|
@@ -41,51 +45,70 @@ class OWProcessPoolExecutor(widget.OWWidget):
|
|
|
41
45
|
|
|
42
46
|
self.cpu_label = self.findChild(QLabel, "cpu_label")
|
|
43
47
|
self.spin_workers = self.findChild(QSpinBox, "spin_workers")
|
|
44
|
-
self.btn_create = self.findChild(QPushButton, "btn_create")
|
|
45
48
|
self.info_label = self.findChild(QLabel, "info_label")
|
|
46
49
|
self.group_box = self.findChild(QGroupBox, "groupBox")
|
|
47
50
|
self.checkBox_send = self.findChild(QCheckBox, "checkBox_send")
|
|
51
|
+
self.pushButton_send = self.findChild(QPushButton, "pushButton_send")
|
|
48
52
|
|
|
53
|
+
# Initialisation de la vue du nombre de CPU et SpinBox
|
|
54
|
+
max_cpus = max(1, pool_exec_utils.available_cpus())
|
|
49
55
|
if self.cpu_label:
|
|
50
56
|
self.cpu_label.setText(pool_exec_utils.cpu_label_text())
|
|
51
57
|
|
|
52
58
|
if self.spin_workers:
|
|
53
59
|
self.spin_workers.setMinimum(1)
|
|
54
|
-
max_cpus = max(1, pool_exec_utils.available_cpus())
|
|
55
60
|
self.spin_workers.setMaximum(max_cpus)
|
|
56
|
-
|
|
61
|
+
|
|
62
|
+
# Restauration du nombre de workers depuis les Settings
|
|
63
|
+
try:
|
|
64
|
+
val = int(self.str_workers)
|
|
65
|
+
except ValueError:
|
|
66
|
+
val = min(4, max_cpus)
|
|
67
|
+
self.spin_workers.setValue(min(max(1, val), max_cpus))
|
|
57
68
|
self.spin_workers.valueChanged.connect(self._on_workers_changed)
|
|
58
69
|
|
|
70
|
+
# Restauration de l'état Auto Send
|
|
59
71
|
if self.checkBox_send:
|
|
60
|
-
self.checkBox_send.setChecked(self.
|
|
61
|
-
self.checkBox_send.
|
|
72
|
+
self.checkBox_send.setChecked(self.str_autosend == "True")
|
|
73
|
+
self.checkBox_send.clicked.connect(self._on_autorun_toggled)
|
|
62
74
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
self.
|
|
75
|
+
# Bouton d'exécution manuelle
|
|
76
|
+
if self.pushButton_send:
|
|
77
|
+
self.pushButton_send.setEnabled(self.str_autosend != "True")
|
|
78
|
+
self.pushButton_send.clicked.connect(self.create_or_update_clicked)
|
|
66
79
|
|
|
67
80
|
self.error("")
|
|
68
81
|
self.warning("")
|
|
69
82
|
self.post_initialized()
|
|
70
83
|
|
|
71
|
-
|
|
72
|
-
|
|
84
|
+
QTimer.singleShot(0, lambda: help_management.override_help_action(self))
|
|
85
|
+
|
|
86
|
+
# Lancement automatique initial si activé dans les Settings
|
|
87
|
+
if self.str_autosend == "True":
|
|
73
88
|
self.create_or_update_clicked()
|
|
74
89
|
|
|
75
90
|
# ------------------------------------------------------------------
|
|
76
|
-
#
|
|
91
|
+
# Settings & UI Synchronization
|
|
77
92
|
# ------------------------------------------------------------------
|
|
78
|
-
def
|
|
79
|
-
|
|
80
|
-
if self.
|
|
81
|
-
self.
|
|
82
|
-
|
|
83
|
-
if self.
|
|
93
|
+
def update_setting_from_qt_view(self):
|
|
94
|
+
"""Met à jour les attributs de Setting à partir des composants Qt."""
|
|
95
|
+
if self.spin_workers:
|
|
96
|
+
self.str_workers = str(self.spin_workers.value())
|
|
97
|
+
|
|
98
|
+
if self.checkBox_send:
|
|
99
|
+
self.str_autosend = "True" if self.checkBox_send.isChecked() else "False"
|
|
100
|
+
|
|
101
|
+
if self.pushButton_send and self.checkBox_send:
|
|
102
|
+
self.pushButton_send.setEnabled(not self.checkBox_send.isChecked())
|
|
103
|
+
|
|
104
|
+
def _on_autorun_toggled(self):
|
|
105
|
+
self.update_setting_from_qt_view()
|
|
106
|
+
if self.str_autosend == "True":
|
|
84
107
|
self.create_or_update_clicked()
|
|
85
108
|
|
|
86
109
|
def _on_workers_changed(self):
|
|
87
|
-
|
|
88
|
-
if self.
|
|
110
|
+
self.update_setting_from_qt_view()
|
|
111
|
+
if self.str_autosend == "True":
|
|
89
112
|
self.create_or_update_clicked()
|
|
90
113
|
|
|
91
114
|
# ------------------------------------------------------------------
|
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
</rect>
|
|
12
12
|
</property>
|
|
13
13
|
<property name="windowTitle">
|
|
14
|
-
<string>
|
|
14
|
+
<string>Process Pool Executor</string>
|
|
15
15
|
</property>
|
|
16
16
|
<widget class="QGroupBox" name="groupBox">
|
|
17
17
|
<property name="geometry">
|
|
18
18
|
<rect>
|
|
19
19
|
<x>10</x>
|
|
20
|
-
<y>
|
|
20
|
+
<y>20</y>
|
|
21
21
|
<width>451</width>
|
|
22
|
-
<height>
|
|
22
|
+
<height>200</height>
|
|
23
23
|
</rect>
|
|
24
24
|
</property>
|
|
25
25
|
<property name="title">
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
<property name="geometry">
|
|
30
30
|
<rect>
|
|
31
31
|
<x>10</x>
|
|
32
|
-
<y>
|
|
32
|
+
<y>20</y>
|
|
33
33
|
<width>431</width>
|
|
34
|
-
<height>
|
|
34
|
+
<height>45</height>
|
|
35
35
|
</rect>
|
|
36
36
|
</property>
|
|
37
37
|
<property name="text">
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
<x>10</x>
|
|
51
51
|
<y>70</y>
|
|
52
52
|
<width>431</width>
|
|
53
|
-
<height>
|
|
53
|
+
<height>20</height>
|
|
54
54
|
</rect>
|
|
55
55
|
</property>
|
|
56
56
|
<property name="text">
|
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
<property name="geometry">
|
|
62
62
|
<rect>
|
|
63
63
|
<x>10</x>
|
|
64
|
-
<y>
|
|
64
|
+
<y>100</y>
|
|
65
65
|
<width>431</width>
|
|
66
|
-
<height>
|
|
66
|
+
<height>20</height>
|
|
67
67
|
</rect>
|
|
68
68
|
</property>
|
|
69
69
|
<property name="text">
|
|
@@ -74,40 +74,27 @@
|
|
|
74
74
|
<property name="geometry">
|
|
75
75
|
<rect>
|
|
76
76
|
<x>10</x>
|
|
77
|
-
<y>
|
|
77
|
+
<y>130</y>
|
|
78
78
|
<width>431</width>
|
|
79
|
-
<height>
|
|
79
|
+
<height>25</height>
|
|
80
80
|
</rect>
|
|
81
81
|
</property>
|
|
82
82
|
</widget>
|
|
83
|
-
<widget class="QPushButton" name="btn_create">
|
|
84
|
-
<property name="geometry">
|
|
85
|
-
<rect>
|
|
86
|
-
<x>10</x>
|
|
87
|
-
<y>170</y>
|
|
88
|
-
<width>431</width>
|
|
89
|
-
<height>23</height>
|
|
90
|
-
</rect>
|
|
91
|
-
</property>
|
|
92
|
-
<property name="text">
|
|
93
|
-
<string>(Re)create / Update executor</string>
|
|
94
|
-
</property>
|
|
95
|
-
</widget>
|
|
96
83
|
</widget>
|
|
97
84
|
<widget class="QPushButton" name="pushButton_send">
|
|
98
85
|
<property name="enabled">
|
|
99
|
-
<bool>
|
|
86
|
+
<bool>true</bool>
|
|
100
87
|
</property>
|
|
101
88
|
<property name="geometry">
|
|
102
89
|
<rect>
|
|
103
90
|
<x>170</x>
|
|
104
|
-
<y>
|
|
91
|
+
<y>235</y>
|
|
105
92
|
<width>291</width>
|
|
106
|
-
<height>
|
|
93
|
+
<height>32</height>
|
|
107
94
|
</rect>
|
|
108
95
|
</property>
|
|
109
96
|
<property name="text">
|
|
110
|
-
<string>
|
|
97
|
+
<string>(Re)create / Update executor</string>
|
|
111
98
|
</property>
|
|
112
99
|
</widget>
|
|
113
100
|
<widget class="QCheckBox" name="checkBox_send">
|
|
@@ -117,9 +104,9 @@
|
|
|
117
104
|
<property name="geometry">
|
|
118
105
|
<rect>
|
|
119
106
|
<x>10</x>
|
|
120
|
-
<y>
|
|
121
|
-
<width>
|
|
122
|
-
<height>
|
|
107
|
+
<y>240</y>
|
|
108
|
+
<width>150</width>
|
|
109
|
+
<height>20</height>
|
|
123
110
|
</rect>
|
|
124
111
|
</property>
|
|
125
112
|
<property name="text">
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/toolViews/designer/link_workflow_manager_ui.ui
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{io4it-4.0.25 → io4it-4.0.26}/orangecontrib/IO4IT/widgets/designer/ow_extract_tables_docx_to_xlsx.ui
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|