intentkit 0.7.5.dev12__py3-none-any.whl → 0.7.5.dev13__py3-none-any.whl

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.

Potentially problematic release.


This version of intentkit might be problematic. Click here for more details.

intentkit/__init__.py CHANGED
@@ -3,7 +3,7 @@
3
3
  A powerful platform for building AI agents with blockchain and cryptocurrency capabilities.
4
4
  """
5
5
 
6
- __version__ = "0.7.5-dev12"
6
+ __version__ = "0.7.5-dev13"
7
7
  __author__ = "hyacinthus"
8
8
  __email__ = "hyacinthus@gmail.com"
9
9
 
intentkit/models/agent.py CHANGED
@@ -1415,16 +1415,7 @@ class Agent(AgentCreate, AgentPublicInfo):
1415
1415
  skills_properties = skills_property.get("properties", {})
1416
1416
 
1417
1417
  if skills_properties:
1418
- # Load all skills from the database
1419
- # Query all skills grouped by category with enabled status
1420
- stmt = select(
1421
- SkillTable.category,
1422
- func.bool_or(SkillTable.enabled).label("any_enabled"),
1423
- ).group_by(SkillTable.category)
1424
- result = await db.execute(stmt)
1425
- category_status = {row.category: row.any_enabled for row in result}
1426
-
1427
- # Query all skills with their price levels for adding x-price-level fields
1418
+ # Query all enabled skills with their price levels for adding x-price-level fields
1428
1419
  skills_stmt = select(
1429
1420
  SkillTable.category,
1430
1421
  SkillTable.config_name,
@@ -1434,8 +1425,12 @@ class Agent(AgentCreate, AgentPublicInfo):
1434
1425
  skills_result = await db.execute(skills_stmt)
1435
1426
  skills_data = {}
1436
1427
  category_price_levels = {}
1428
+ enabled_categories = set()
1437
1429
 
1438
1430
  for row in skills_result:
1431
+ # Collect enabled categories using a set for deduplication
1432
+ enabled_categories.add(row.category)
1433
+
1439
1434
  if row.category not in skills_data:
1440
1435
  skills_data[row.category] = {}
1441
1436
  category_price_levels[row.category] = []
@@ -1458,11 +1453,8 @@ class Agent(AgentCreate, AgentPublicInfo):
1458
1453
 
1459
1454
  # Process each skill in the schema
1460
1455
  for skill_category in skill_keys:
1461
- if skill_category not in category_status:
1462
- # If category not found in database, remove it from schema
1463
- skills_properties.pop(skill_category, None)
1464
- elif not category_status[skill_category]:
1465
- # If category exists but all skills are disabled, remove it
1456
+ if skill_category not in enabled_categories:
1457
+ # If category not found in enabled categories, remove it from schema
1466
1458
  skills_properties.pop(skill_category, None)
1467
1459
  elif filter_owner_api_skills and cls._is_agent_owner_only_skill(
1468
1460
  skills_properties[skill_category]
@@ -9,7 +9,7 @@ from pydantic import BaseModel, Field
9
9
  from intentkit.abstracts.skill import SkillStoreABC
10
10
  from intentkit.skills.venice_audio.base import VeniceAudioBaseTool
11
11
  from intentkit.skills.venice_audio.input import AllowedAudioFormat, VeniceAudioInput
12
- from intentkit.utils.s3 import FileType, store_file_bytes
12
+ from intentkit.utils.s3 import store_file
13
13
 
14
14
  logger = logging.getLogger(__name__)
15
15
 
@@ -48,7 +48,7 @@ class VeniceAudioTool(VeniceAudioBaseTool):
48
48
  ) -> Dict[str, Any]:
49
49
  """
50
50
  Generates audio using the configured voice model via Venice AI TTS /audio/speech endpoint.
51
- Stores the resulting audio using store_file_bytes.
51
+ Stores the resulting audio using the generic S3 helper.
52
52
  Returns a dictionary containing audio details on success, or API error details on failure.
53
53
  """
54
54
  context = self.get_context()
@@ -155,11 +155,32 @@ class VeniceAudioTool(VeniceAudioBaseTool):
155
155
  key = f"{self.category}/{voice_model}/{audio_hash}.{file_extension}"
156
156
 
157
157
  size_limit = 1024 * 20 # 20Mb Size limit
158
- stored_url = await store_file_bytes(
159
- file_bytes=audio_bytes,
158
+ audio_size = len(audio_bytes)
159
+ if audio_size > size_limit:
160
+ message = f"Generated audio exceeds the allowed size of {size_limit} bytes."
161
+ logger.error(
162
+ "Failed to store audio (Voice: %s): %s",
163
+ voice_model,
164
+ message,
165
+ )
166
+ return {
167
+ "error": True,
168
+ "error_type": "FileSizeLimitExceeded",
169
+ "message": message,
170
+ "voice_model": voice_model,
171
+ "requested_format": final_response_format,
172
+ }
173
+
174
+ mime_type = (
175
+ content_type_header.split(";", 1)[0].strip()
176
+ if content_type_header
177
+ else None
178
+ )
179
+ stored_url = await store_file(
180
+ content=audio_bytes,
160
181
  key=key,
161
- file_type=FileType.AUDIO,
162
- size_limit_bytes=size_limit,
182
+ content_type=mime_type,
183
+ size=audio_size,
163
184
  )
164
185
 
165
186
  if not stored_url:
@@ -182,7 +203,7 @@ class VeniceAudioTool(VeniceAudioBaseTool):
182
203
  return {
183
204
  "audio_url": stored_url,
184
205
  "audio_bytes_sha256": audio_hash,
185
- "content_type": content_type_header,
206
+ "content_type": mime_type or content_type_header,
186
207
  "voice_model": voice_model,
187
208
  "tts_engine": tts_model_id,
188
209
  "speed": speed if speed is not None else 1.0,
intentkit/utils/s3.py CHANGED
@@ -182,6 +182,59 @@ class FileType(str, Enum):
182
182
  PDF = "pdf"
183
183
 
184
184
 
185
+ async def store_file(
186
+ content: bytes,
187
+ key: str,
188
+ content_type: Optional[str] = None,
189
+ size: Optional[int] = None,
190
+ ) -> str:
191
+ """Store raw file bytes with automatic content type detection."""
192
+ if not _client or not _bucket or not _prefix or not _cdn_url:
193
+ logger.info("S3 not initialized. Cannot store file bytes.")
194
+ return ""
195
+
196
+ if not content:
197
+ raise ValueError("File content cannot be empty")
198
+
199
+ actual_size = len(content)
200
+ if size is not None and size != actual_size:
201
+ raise ValueError(
202
+ f"Provided size {size} does not match actual content size {actual_size} bytes"
203
+ )
204
+
205
+ effective_size = size if size is not None else actual_size
206
+
207
+ detected_content_type = content_type
208
+ if not detected_content_type:
209
+ kind = filetype.guess(content)
210
+ detected_content_type = (
211
+ kind.mime if kind and kind.mime else "application/octet-stream"
212
+ )
213
+
214
+ prefixed_key = f"{_prefix}{key}"
215
+ file_obj = BytesIO(content)
216
+
217
+ logger.info(
218
+ "Uploading file to S3 with content type %s and size %s bytes",
219
+ detected_content_type,
220
+ effective_size,
221
+ )
222
+
223
+ _client.upload_fileobj(
224
+ file_obj,
225
+ _bucket,
226
+ prefixed_key,
227
+ ExtraArgs={
228
+ "ContentType": detected_content_type,
229
+ "ContentDisposition": "inline",
230
+ },
231
+ )
232
+
233
+ cdn_url = f"{_cdn_url}/{prefixed_key}"
234
+ logger.info("File uploaded successfully to %s", cdn_url)
235
+ return cdn_url
236
+
237
+
185
238
  async def store_file_bytes(
186
239
  file_bytes: bytes,
187
240
  key: str,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: intentkit
3
- Version: 0.7.5.dev12
3
+ Version: 0.7.5.dev13
4
4
  Summary: Intent-based AI Agent Platform - Core Package
5
5
  Project-URL: Homepage, https://github.com/crestalnetwork/intentkit
6
6
  Project-URL: Repository, https://github.com/crestalnetwork/intentkit
@@ -1,4 +1,4 @@
1
- intentkit/__init__.py,sha256=RnzjeFMcq6VPro5wJazURqVrmSzAFezYc9pQfYskF5Y,384
1
+ intentkit/__init__.py,sha256=WCRarWbBBC8guMPMfmalWRblSMCx17YzO1FqXtdlpzo,384
2
2
  intentkit/abstracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  intentkit/abstracts/agent.py,sha256=108gb5W8Q1Sy4G55F2_ZFv2-_CnY76qrBtpIr0Oxxqk,1489
4
4
  intentkit/abstracts/api.py,sha256=ZUc24vaQvQVbbjznx7bV0lbbQxdQPfEV8ZxM2R6wZWo,166
@@ -21,7 +21,7 @@ intentkit/core/credit.py,sha256=b4f4T6G6eeBTMe0L_r8awWtXgUnqiog4IUaymDPYym0,7558
21
21
  intentkit/core/engine.py,sha256=DoGqfhNK35sFeqMlFLyKR_NUDf1YXf4yihSfw7kufmU,36177
22
22
  intentkit/core/node.py,sha256=7h9zgDSd928bzUi3m3EZnKkhbwqlbRAQUr_uz7gKB5Y,8880
23
23
  intentkit/core/prompt.py,sha256=ssiyKHDNIjQOLU0KwUlIFX3jy51TqgeKOxrwnW4HBkw,15875
24
- intentkit/models/agent.py,sha256=ATRNAlmO1YN995kQa_IVAW7TUPOxAcDZDRTdHX95X_A,67442
24
+ intentkit/models/agent.py,sha256=usZjgzW7mb0uQ1SIVFM944sTB0ul5-Xr8FOC0YTKswE,66942
25
25
  intentkit/models/agent_data.py,sha256=5zq3EPKnygT2P1OHc2IfEmL8hXkjeBND6sJ0JJsvQJg,28370
26
26
  intentkit/models/agent_public.json,sha256=0X8Bd2WOobDJLsok8avWNzmzu4uvKSGEyy6Myn53eT4,2802
27
27
  intentkit/models/agent_schema.json,sha256=hFGUE57JIiN8V4olgLf2LBXPejA2QLiQoFc6riM1UFo,17139
@@ -357,7 +357,7 @@ intentkit/skills/venice_audio/__init__.py,sha256=E39CeSUHRoGV9IxNUtwo-nCp0Yfq5rv
357
357
  intentkit/skills/venice_audio/base.py,sha256=1oxHrmDXpBZbA7q2BqatlpuY-X3uwhK22T8QZjKmkqw,4845
358
358
  intentkit/skills/venice_audio/input.py,sha256=nWsbW40Bd-Q331PpBZ-NBcsgw3pqEWsWIvY0lsbNR4A,1887
359
359
  intentkit/skills/venice_audio/schema.json,sha256=g3cb9zJvinnRrilvNIAdG8qivgGyB7sHCEC8392MXhY,5268
360
- intentkit/skills/venice_audio/venice_audio.py,sha256=2EfCkC-MH1p-evTf594yHKNiJiCmAlIPLuYgXF48Hlk,10365
360
+ intentkit/skills/venice_audio/venice_audio.py,sha256=3xIUbNZ_ZZ5J2FYJzGaJ0ZCwX_IpAouVuoTyl0JI72Q,11305
361
361
  intentkit/skills/venice_audio/venice_logo.jpg,sha256=XDnVdh3V8UuJjAeSmp4rbqhTKn0yjRI6M_6z1DSs8cA,13342
362
362
  intentkit/skills/venice_image/README.md,sha256=79NWUOaYWeFLOhR7m424pLIZ7VT0fhkxSBcohoy8Oh0,5017
363
363
  intentkit/skills/venice_image/__init__.py,sha256=fPq9OS8er67cn3zyo9H_7iEj5cSUu7nOmqhhjwG9xNs,5841
@@ -415,10 +415,10 @@ intentkit/utils/chain.py,sha256=PubXjJM_kt6NCwzpKm5uXQ596QvKFLfr2L_DP9ntHAs,1516
415
415
  intentkit/utils/error.py,sha256=fZOZ9CPrU08veSyDBoNf44UjkojpsyFMEr2SxEdlSZA,4898
416
416
  intentkit/utils/logging.py,sha256=bhwZi5vscjBTd9kaNp_L6ijrfv9Sl3lsr4ARaUB4Iec,2389
417
417
  intentkit/utils/random.py,sha256=DymMxu9g0kuQLgJUqalvgksnIeLdS-v0aRk5nQU0mLI,452
418
- intentkit/utils/s3.py,sha256=9trQNkKQ5VgxWsewVsV8Y0q_pXzGRvsCYP8xauyUYkg,8549
418
+ intentkit/utils/s3.py,sha256=A8Nsx5QJyLsxhj9g7oHNy2-m24tjQUhC9URm8Qb1jFw,10057
419
419
  intentkit/utils/slack_alert.py,sha256=s7UpRgyzLW7Pbmt8cKzTJgMA9bm4EP-1rQ5KXayHu6E,2264
420
420
  intentkit/utils/tx.py,sha256=2yLLGuhvfBEY5n_GJ8wmIWLCzn0FsYKv5kRNzw_sLUI,1454
421
- intentkit-0.7.5.dev12.dist-info/METADATA,sha256=qFBZAvX5suIuqP5k7ndeAXh7mhyDtAh5awVKf9-4IcU,6410
422
- intentkit-0.7.5.dev12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
423
- intentkit-0.7.5.dev12.dist-info/licenses/LICENSE,sha256=Bln6DhK-LtcO4aXy-PBcdZv2f24MlJFm_qn222biJtE,1071
424
- intentkit-0.7.5.dev12.dist-info/RECORD,,
421
+ intentkit-0.7.5.dev13.dist-info/METADATA,sha256=Y360u6Lp9aLakwP2Kj9eN-RmhQbwPyCT5j1VgxoA42k,6410
422
+ intentkit-0.7.5.dev13.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
423
+ intentkit-0.7.5.dev13.dist-info/licenses/LICENSE,sha256=Bln6DhK-LtcO4aXy-PBcdZv2f24MlJFm_qn222biJtE,1071
424
+ intentkit-0.7.5.dev13.dist-info/RECORD,,