Skip to content

Commit 60f5ee1

Browse files
committed
v2.0.4 changes:
Changes to Openai_API methods `setup()` and `file_upload(): Compose instructions and include FURTHER_INSTRUCTIONS: * instructions = f"You are {self.assistant_name}, {self.your_name}'s personal AI assistant." * further = (self.config.get("FURTHER_INSTRUCTIONS") or "").strip() * if further: instructions = f"{instructions}\n\n{further}" Update assistant with vector store and sync instructions in a single call: * Build update_kwargs with tool_resources. * If assistant.instructions != instructions, include "instructions" in update_kwargs. * Call self.client.beta.assistants.update(**update_kwargs). * When the assistant’s instructions need updating (due to changes in YOUR_NAME or FURTHER_INSTRUCTIONS), the app will now print: Synced assistant instructions with settings (YOUR_NAME and FURTHER_INSTRUCTIONS). This message only appears if instructions were actually changed during setup; otherwise, it stays quiet. Added robust error handling and logging for vector store upload and streaming. * Upload failures no longer crash startup; a clear status is returned and printed by the main flow. * Assistant update issues don’t prevent the app from starting a chat; you’ll see a clear warning. * Streaming now has a safety net for unforeseen errors, with logging to help diagnose.
1 parent c75c052 commit 60f5ee1

File tree

1 file changed

+122
-27
lines changed

1 file changed

+122
-27
lines changed

openai-assistant

Lines changed: 122 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ openai-assistant v2
44
Copyright 2025 J Adams jfa63[at]duck[dot]com
55
Released under the 2-Clause BSD license.
66
"""
7-
__version__ = 'v2.0.3'
7+
__version__ = 'v2.0.4'
88
__author__ = 'J. Adams jfa63[at]duck[dot]com'
99

1010
# Builtin imports
@@ -228,33 +228,98 @@ class Openai_API():
228228
"""
229229
Uploads a file.
230230
"""
231-
# Skip if the file is empty or missing
232231
if not os.path.isfile(filename) or os.path.getsize(filename) == 0:
233-
# Return a 'fake' VectorStoreFileBatch
234232
return VectorStoreFileBatch(id="",
235233
created_at=0,
236234
file_counts={'cancelled': 1,
237235
'completed': 0,
238236
'failed': 0,
239237
'in_progress': 0,
240-
'total': 0
241-
},
238+
'total': 0},
242239
object="vector_store.files_batch",
243240
vector_store_id="",
244241
status="cancelled")
245242

246243
file_paths = [filename]
247-
file_streams = [open(path, "rb") for path in file_paths]
248-
249-
# Upload files to the vector store
250-
file_batch = self.client.vector_stores.file_batches.upload_and_poll(
251-
vector_store_id=self.vector_store.id, files=file_streams
252-
)
253-
254-
for fs in file_streams:
255-
fs.close()
256-
257-
return file_batch
244+
file_streams = []
245+
try:
246+
for path in file_paths:
247+
file_streams.append(open(path, "rb"))
248+
file_batch = self.client.vector_stores.file_batches.upload_and_poll(
249+
vector_store_id=self.vector_store.id, files=file_streams
250+
)
251+
return file_batch
252+
except openai.APIConnectionError as e:
253+
try:
254+
if lf:
255+
lf.write(str(e))
256+
except Exception:
257+
pass
258+
return VectorStoreFileBatch(id="",
259+
created_at=0,
260+
file_counts={'cancelled': 0,
261+
'completed': 0,
262+
'failed': 1,
263+
'in_progress': 0,
264+
'total': 0},
265+
object="vector_store.files_batch",
266+
vector_store_id="",
267+
status="failed")
268+
except openai.RateLimitError as e:
269+
try:
270+
if lf:
271+
lf.write(str(e))
272+
except Exception:
273+
pass
274+
return VectorStoreFileBatch(id="",
275+
created_at=0,
276+
file_counts={'cancelled': 0,
277+
'completed': 0,
278+
'failed': 1,
279+
'in_progress': 0,
280+
'total': 0},
281+
object="vector_store.files_batch",
282+
vector_store_id="",
283+
status="failed")
284+
except openai.APIStatusError as e:
285+
try:
286+
if lf:
287+
lf.write(str(e.status_code))
288+
lf.write(str(e.response))
289+
except Exception:
290+
pass
291+
return VectorStoreFileBatch(id="",
292+
created_at=0,
293+
file_counts={'cancelled': 0,
294+
'completed': 0,
295+
'failed': 1,
296+
'in_progress': 0,
297+
'total': 0},
298+
object="vector_store.files_batch",
299+
vector_store_id="",
300+
status="failed")
301+
except Exception as e:
302+
try:
303+
if lf:
304+
lf.write(str(e))
305+
except Exception:
306+
pass
307+
return VectorStoreFileBatch(id="",
308+
created_at=0,
309+
file_counts={'cancelled': 0,
310+
'completed': 0,
311+
'failed': 1,
312+
'in_progress': 0,
313+
'total': 0},
314+
object="vector_store.files_batch",
315+
vector_store_id="",
316+
status="failed")
317+
finally:
318+
for fs in file_streams:
319+
try:
320+
fs.close()
321+
except Exception:
322+
pass
258323
# End file_upload()
259324

260325

@@ -263,10 +328,12 @@ class Openai_API():
263328
Creates Assistant instance and Vector Store.
264329
"""
265330
## Assistant setup
266-
# Default baseline instructions
267-
# Further, custom instructions can be added in
268-
# ~/.openai/settings.py
331+
# Compose baseline instructions and append any user-provided
332+
# additional guidance from settings (FURTHER_INSTRUCTIONS).
269333
instructions = f"You are {self.assistant_name}, {self.your_name}'s personal AI assistant."
334+
further = (self.config.get("FURTHER_INSTRUCTIONS") or "").strip()
335+
if further:
336+
instructions = f"{instructions}\n\n{further}"
270337

271338
if self.config.get("ASSISTANT_ID"):
272339
self.assistant = self.client.beta.assistants.retrieve(
@@ -309,11 +376,32 @@ class Openai_API():
309376
## Upload chat_log.txt
310377
upload = self.file_upload(logfile)
311378

312-
## Update assistant with vector store
313-
self.assistant = self.client.beta.assistants.update(
314-
assistant_id=self.assistant.id,
315-
tool_resources={"file_search": {"vector_store_ids": [self.vector_store.id]}},
316-
)
379+
## Update assistant with vector store and ensure instructions are in-sync
380+
update_kwargs = {
381+
"assistant_id": self.assistant.id,
382+
"tool_resources": {"file_search": {"vector_store_ids": [self.vector_store.id]}},
383+
}
384+
updated_instructions = False
385+
try:
386+
if (self.assistant.instructions or "") != instructions:
387+
update_kwargs["instructions"] = instructions
388+
updated_instructions = True
389+
except Exception:
390+
update_kwargs["instructions"] = instructions
391+
updated_instructions = True
392+
393+
try:
394+
self.assistant = self.client.beta.assistants.update(**update_kwargs)
395+
except Exception as e:
396+
try:
397+
if lf:
398+
lf.write(str(e))
399+
except Exception:
400+
pass
401+
print("[red]Warning:[/] Failed to update assistant tool resources/instructions; proceeding without vector store update.")
402+
else:
403+
if updated_instructions:
404+
print("Synced assistant instructions with settings: [#f5d676]YOUR_NAME[/] and [#f5d676]FURTHER_INSTRUCTIONS[/].")
317405

318406
## Create thread
319407
self.thread = self.client.beta.threads.create()
@@ -368,8 +456,15 @@ class Openai_API():
368456
lf.write(str(e.status_code))
369457
lf.write(str(e.response))
370458
except Exception as logex:
371-
print(f"[red]Error writing APIStatusError to log: {logex}")
372-
return "A non-200-range status code was received. Check log."
459+
print(f'[red]Error writing APIStatusError to log: {logex}')
460+
return 'A non-200-range status code was received. Check log.'
461+
except Exception as e:
462+
try:
463+
if lf:
464+
lf.write(str(e))
465+
except Exception as logex:
466+
print(f'[red]Error writing unexpected exception to log: {logex}')
467+
return 'An unexpected error occurred while streaming. Check log.'
373468
return resp
374469
# End send_query()
375470
# End Class Openai_API
@@ -524,7 +619,7 @@ if __name__ == "__main__":
524619
print("Not uploading empty chat log.")
525620
elif status == "completed":
526621
print(f"Uploaded [#d5d676]{logfile}[/]\n")
527-
else:
622+
elif status == "failed":
528623
print(f"Upload of [red]{logfile}[/] failed!\n")
529624
# a little time to read msg
530625
sleep(3)

0 commit comments

Comments
 (0)