autonomous-app 0.3.37__tar.gz → 0.3.38__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.
Files changed (68) hide show
  1. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/PKG-INFO +1 -1
  2. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/__init__.py +1 -1
  3. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/ai/models/local_model.py +114 -36
  4. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous_app.egg-info/PKG-INFO +1 -1
  5. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/README.md +0 -0
  6. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/pyproject.toml +0 -0
  7. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/requirements.txt +0 -0
  8. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/setup.cfg +0 -0
  9. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/setup.py +0 -0
  10. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/ai/__init__.py +0 -0
  11. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/ai/audioagent.py +0 -0
  12. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/ai/baseagent.py +0 -0
  13. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/ai/imageagent.py +0 -0
  14. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/ai/jsonagent.py +0 -0
  15. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/ai/models/__init__.py +0 -0
  16. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/ai/models/gemini.py +0 -0
  17. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/ai/textagent.py +0 -0
  18. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/apis/version_control/GHCallbacks.py +0 -0
  19. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/apis/version_control/GHOrganization.py +0 -0
  20. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/apis/version_control/GHRepo.py +0 -0
  21. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/apis/version_control/GHVersionControl.py +0 -0
  22. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/apis/version_control/__init__.py +0 -0
  23. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/auth/__init__.py +0 -0
  24. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/auth/autoauth.py +0 -0
  25. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/auth/github.py +0 -0
  26. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/auth/google.py +0 -0
  27. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/auth/user.py +0 -0
  28. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/cli.py +0 -0
  29. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/__init__.py +0 -0
  30. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/base/__init__.py +0 -0
  31. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/base/common.py +0 -0
  32. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/base/datastructures.py +0 -0
  33. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/base/document.py +0 -0
  34. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/base/fields.py +0 -0
  35. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/base/metaclasses.py +0 -0
  36. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/base/utils.py +0 -0
  37. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/common.py +0 -0
  38. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/connection.py +0 -0
  39. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/context_managers.py +0 -0
  40. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/db_sync.py +0 -0
  41. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/dereference.py +0 -0
  42. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/document.py +0 -0
  43. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/errors.py +0 -0
  44. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/fields.py +0 -0
  45. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/mongodb_support.py +0 -0
  46. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/pymongo_support.py +0 -0
  47. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/queryset/__init__.py +0 -0
  48. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/queryset/base.py +0 -0
  49. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/queryset/field_list.py +0 -0
  50. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/queryset/manager.py +0 -0
  51. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/queryset/queryset.py +0 -0
  52. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/queryset/transform.py +0 -0
  53. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/queryset/visitor.py +0 -0
  54. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/db/signals.py +0 -0
  55. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/logger.py +0 -0
  56. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/model/autoattr.py +0 -0
  57. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/model/automodel.py +0 -0
  58. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/storage/__init__.py +0 -0
  59. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/storage/imagestorage.py +0 -0
  60. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/storage/localstorage.py +0 -0
  61. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/taskrunner/__init__.py +0 -0
  62. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/taskrunner/autotasks.py +0 -0
  63. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/taskrunner/task_router.py +0 -0
  64. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous/utils/markdown.py +0 -0
  65. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous_app.egg-info/SOURCES.txt +0 -0
  66. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous_app.egg-info/dependency_links.txt +0 -0
  67. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous_app.egg-info/requires.txt +0 -0
  68. {autonomous_app-0.3.37 → autonomous_app-0.3.38}/src/autonomous_app.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: autonomous-app
3
- Version: 0.3.37
3
+ Version: 0.3.38
4
4
  Summary: Containerized application framework built on Flask with additional libraries and tools for rapid development of web applications.
5
5
  Author-email: Steven A Moore <samoore@binghamton.edu>
6
6
  Project-URL: homepage, https://github.com/Sallenmoore/autonomous
@@ -1,4 +1,4 @@
1
- __version__ = "0.3.37"
1
+ __version__ = "0.3.38"
2
2
 
3
3
  from dotenv import load_dotenv
4
4
 
@@ -2,13 +2,8 @@ import io
2
2
  import json
3
3
  import os
4
4
  import random
5
- import re
6
5
 
7
- import numpy as np
8
- import pymongo
9
- import redis
10
6
  import requests
11
- from bson.objectid import ObjectId
12
7
  from pydub import AudioSegment
13
8
 
14
9
  from autonomous import log
@@ -44,17 +39,39 @@ class LocalAIModel(AutoModel):
44
39
  return json.dumps(schema, indent=2)
45
40
 
46
41
  def _clean_json_response(self, text):
47
- """Helper to strip markdown artifacts from JSON responses."""
42
+ """
43
+ Robust cleaner for Llama 3 outputs.
44
+ It handles markdown blocks, chatter before/after, and malformed endings.
45
+ """
48
46
  text = text.strip()
49
- # Remove ```json ... ``` or just ``` ... ``` wrapper
50
- if text.startswith("```"):
51
- # Find the first newline to skip the language tag (e.g., "json")
52
- first_newline = text.find("\n")
53
- if first_newline != -1:
54
- text = text[first_newline + 1 :]
55
- # Remove the closing backticks
56
- if text.endswith("```"):
57
- text = text[:-3]
47
+
48
+ # 1. Strip Markdown Code Blocks (```json ... ```)
49
+ if "```" in text:
50
+ import re
51
+
52
+ # Regex to capture content inside ```json ... ``` or just ``` ... ```
53
+ # flags=re.DOTALL allows . to match newlines
54
+ pattern = r"```(?:json)?\s*(\{.*?\})\s*```"
55
+ match = re.search(pattern, text, re.DOTALL)
56
+ if match:
57
+ text = match.group(1)
58
+ else:
59
+ # Fallback: simple finding if regex fails due to weird chars
60
+ start = text.find("```")
61
+ end = text.rfind("```")
62
+ # Adjust start to skip the "json" part if present
63
+ first_newline = text.find("\n", start)
64
+ if first_newline != -1 and first_newline < end:
65
+ text = text[first_newline:end]
66
+
67
+ # 2. Heuristic extraction: Find the first '{' and the last '}'
68
+ # This fixes cases where Llama says "Here is the JSON: { ... }"
69
+ start_idx = text.find("{")
70
+ end_idx = text.rfind("}")
71
+
72
+ if start_idx != -1 and end_idx != -1:
73
+ text = text[start_idx : end_idx + 1]
74
+
58
75
  return text.strip()
59
76
 
60
77
  def generate_json(
@@ -62,51 +79,60 @@ class LocalAIModel(AutoModel):
62
79
  ):
63
80
  schema_str = self._convert_tools_to_json_schema(function)
64
81
 
65
- # 1. Base System Prompt with Context Anchoring
82
+ # 1. Improved System Prompt
83
+ # We explicitly warn about nested quotes, which is the #1 killer of complex JSON
66
84
  full_system_prompt = (
67
85
  f"{self.instructions}. {additional_instructions}\n"
68
86
  f"You are a strict JSON generator. Output ONLY a valid JSON object matching this schema:\n"
69
87
  f"{schema_str}\n"
70
- f"IMPORTANT: Do not include markdown formatting (like ```json), introductions, or explanations.\n"
88
+ f"IMPORTANT RULES:\n"
89
+ f"1. Do not include markdown formatting or explanations.\n"
90
+ f"2. DOUBLE CHECK nested quotes inside strings. Escape them properly.\n"
91
+ f"3. Ensure all arrays and objects are closed.\n"
71
92
  )
72
93
 
73
94
  if context:
74
95
  full_system_prompt += (
75
96
  f"\n\n### GROUND TRUTH CONTEXT ###\n"
76
- f"You must strictly adhere to the following context. "
77
- f"If this context contradicts your internal knowledge (e.g., physics, facts), "
78
- f"YOU MUST FOLLOW THE CONTEXT.\n"
97
+ f"Adhere strictly to this context:\n"
79
98
  f"{json.dumps(context, indent=2)}"
80
99
  )
81
100
  elif uri:
82
101
  full_system_prompt += f"Use the following URI for reference: {uri}"
83
102
 
84
- # 3. Send to Ollama with JSON Mode
103
+ # 3. Payload with INCREASED CONTEXT and LOWER TEMPERATURE
85
104
  payload = {
86
105
  "model": self._json_model,
87
106
  "messages": [
88
107
  {"role": "system", "content": full_system_prompt},
89
108
  {"role": "user", "content": message},
90
109
  ],
91
- "format": "json", # <--- CRITICAL: Forces valid JSON output
110
+ "format": "json",
92
111
  "stream": False,
93
112
  "keep_alive": "24h",
113
+ "options": {
114
+ "num_ctx": 8192, # <--- Prevents cutoff on large schemas
115
+ "temperature": 0.2, # <--- Increases structural stability
116
+ },
94
117
  }
95
118
 
119
+ log("==== LocalAI JSON Payload ====", payload, _print=True)
120
+ result_text = ""
96
121
  try:
97
122
  # print(f"==== {self._ollama_url}: LocalAI JSON Payload ====")
98
123
  response = requests.post(f"{self._ollama_url}/chat", json=payload)
124
+ log(response)
99
125
  response.raise_for_status()
100
126
 
101
127
  result_text = response.json().get("message", {}).get("content", "{}")
102
128
 
103
- # Clean up potential markdown artifacts
129
+ # Clean
104
130
  clean_text = self._clean_json_response(result_text)
105
131
 
106
132
  # Parse
107
133
  result_dict = json.loads(clean_text)
108
134
 
109
- # Unwrap if the model nested it inside "parameters" (common Llama quirk)
135
+ # Unwrap
110
136
  if "parameters" in result_dict and isinstance(
111
137
  result_dict["parameters"], dict
112
138
  ):
@@ -116,8 +142,16 @@ class LocalAIModel(AutoModel):
116
142
  return result_dict
117
143
 
118
144
  except Exception as e:
145
+ # If it fails, print the RAW text so you can see WHERE it broke.
119
146
  log(f"==== LocalAI JSON Error: {e} ====", _print=True)
120
- raise e
147
+ if result_text:
148
+ log(
149
+ f"--- FAILED RAW OUTPUT ---\n{result_text}\n-----------------------",
150
+ _print=True,
151
+ )
152
+
153
+ # Returning empty prevents the whole app from dying on one bad generation.
154
+ return {}
121
155
 
122
156
  def generate_text(self, message, additional_instructions="", uri="", context={}):
123
157
  # 1. Base System Prompt
@@ -208,6 +242,27 @@ class LocalAIModel(AutoModel):
208
242
  log(f"TTS Error: {e}", _print=True)
209
243
  return None
210
244
 
245
+ # ... inside LocalAIModel class ...
246
+
247
+ def _get_dimensions(self, aspect_ratio):
248
+ """
249
+ Maps abstract aspect ratios to optimal SDXL resolutions.
250
+ SDXL performs best at ~1024x1024 total pixels.
251
+ """
252
+ resolutions = {
253
+ "1:1": (1024, 1024),
254
+ "3:4": (896, 1152),
255
+ "4:3": (1152, 896),
256
+ "16:9": (1216, 832),
257
+ "2K": (2048, 1080),
258
+ "4K": (3840, 2160),
259
+ "9:16": (832, 1216),
260
+ "3:2": (1216, 832),
261
+ "2:3": (832, 1216),
262
+ }
263
+ # Default to 1:1 (1024x1024) if unknown
264
+ return resolutions.get(aspect_ratio, (1024, 1024))
265
+
211
266
  def generate_image(
212
267
  self,
213
268
  prompt,
@@ -216,32 +271,55 @@ class LocalAIModel(AutoModel):
216
271
  aspect_ratio="3:4",
217
272
  image_size="2K",
218
273
  ):
274
+ # 1. CLIP Token Limit Fix (Auto-Summarize)
275
+ if len(prompt) > 300:
276
+ log("⚠️ Prompt exceeds CLIP limit. rewriting...", _print=True)
277
+ summary_instruction = (
278
+ "Convert the description into a comma-separated Stable Diffusion prompt. "
279
+ "Keep visual elements and style. Under 50 words."
280
+ )
281
+ new_prompt = self.generate_text(
282
+ message=prompt, additional_instructions=summary_instruction, context={}
283
+ )
284
+ if new_prompt and len(new_prompt) > 10:
285
+ prompt = new_prompt
286
+
287
+ # 2. Resolution Calculation
288
+ width, height = self._get_dimensions(aspect_ratio)
289
+
290
+ # 3. Construct Payload
291
+ # We send both the abstract params (for logging/metadata)
292
+ # and the concrete pixels (for the engine).
293
+ data = {
294
+ "prompt": prompt,
295
+ "negative_prompt": negative_prompt,
296
+ "aspect_ratio": aspect_ratio,
297
+ "width": width, # <--- Calculated Pixel Width
298
+ "height": height, # <--- Calculated Pixel Height
299
+ }
300
+
219
301
  try:
220
- data = {"prompt": prompt, "negative_prompt": negative_prompt}
302
+ # Handle Files (Dict -> List of Tuples for requests)
221
303
  img_files = {}
222
- if files:
304
+ if files and isinstance(files, dict):
223
305
  for fn, f_bytes in files.items():
224
306
  if isinstance(f_bytes, bytes):
225
307
  file_obj = io.BytesIO(f_bytes)
226
308
  else:
227
309
  file_obj = f_bytes
228
310
  img_files["file"] = (fn, file_obj, "image/png")
311
+
312
+ # Send Request
313
+ if img_files:
229
314
  response = requests.post(
230
315
  f"{self._media_url}/generate-image", data=data, files=img_files
231
316
  )
232
317
  else:
233
318
  response = requests.post(f"{self._media_url}/generate-image", data=data)
319
+
234
320
  response.raise_for_status()
235
321
  return response.content
322
+
236
323
  except Exception as e:
237
324
  log(f"Image Gen Error: {e}", _print=True)
238
325
  return None
239
-
240
- def list_voices(self, filters=[]):
241
- if not filters:
242
- return list(self.VOICES.keys())
243
- voices = []
244
- for voice, attribs in self.VOICES.items():
245
- if any(f.lower() in attribs for f in filters):
246
- voices.append(voice)
247
- return voices
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: autonomous-app
3
- Version: 0.3.37
3
+ Version: 0.3.38
4
4
  Summary: Containerized application framework built on Flask with additional libraries and tools for rapid development of web applications.
5
5
  Author-email: Steven A Moore <samoore@binghamton.edu>
6
6
  Project-URL: homepage, https://github.com/Sallenmoore/autonomous