veadk-python 0.2.5__py3-none-any.whl → 0.2.7__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 veadk-python might be problematic. Click here for more details.

Files changed (94) hide show
  1. veadk/agent.py +29 -22
  2. veadk/agent_builder.py +94 -0
  3. veadk/auth/__init__.py +13 -0
  4. veadk/auth/base_auth.py +22 -0
  5. veadk/auth/veauth/__init__.py +13 -0
  6. veadk/auth/veauth/apmplus_veauth.py +65 -0
  7. veadk/auth/veauth/ark_veauth.py +77 -0
  8. veadk/auth/veauth/base_veauth.py +50 -0
  9. veadk/auth/veauth/cozeloop_veauth.py +13 -0
  10. veadk/auth/veauth/prompt_pilot_veauth.py +60 -0
  11. veadk/auth/veauth/vesearch_veauth.py +62 -0
  12. veadk/cli/cli.py +2 -0
  13. veadk/cli/cli_deploy.py +5 -2
  14. veadk/cli/cli_init.py +25 -6
  15. veadk/cli/cli_pipeline.py +220 -0
  16. veadk/cli/cli_prompt.py +4 -4
  17. veadk/config.py +45 -81
  18. veadk/configs/__init__.py +13 -0
  19. veadk/configs/database_configs.py +83 -0
  20. veadk/configs/model_configs.py +42 -0
  21. veadk/configs/tool_configs.py +42 -0
  22. veadk/configs/tracing_configs.py +110 -0
  23. veadk/consts.py +32 -1
  24. veadk/database/database_adapter.py +256 -3
  25. veadk/database/kv/redis_database.py +47 -0
  26. veadk/database/local_database.py +23 -4
  27. veadk/database/relational/mysql_database.py +58 -0
  28. veadk/database/vector/opensearch_vector_database.py +6 -3
  29. veadk/database/viking/viking_database.py +272 -36
  30. veadk/integrations/ve_code_pipeline/__init__.py +13 -0
  31. veadk/integrations/ve_code_pipeline/ve_code_pipeline.py +431 -0
  32. veadk/integrations/ve_cozeloop/__init__.py +13 -0
  33. veadk/integrations/ve_cozeloop/ve_cozeloop.py +96 -0
  34. veadk/integrations/ve_cr/__init__.py +13 -0
  35. veadk/integrations/ve_cr/ve_cr.py +220 -0
  36. veadk/integrations/ve_faas/template/cookiecutter.json +3 -2
  37. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/deploy.py +2 -2
  38. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/agent.py +1 -1
  39. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +24 -1
  40. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt +3 -1
  41. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh +1 -12
  42. veadk/integrations/ve_faas/ve_faas.py +352 -35
  43. veadk/integrations/ve_faas/web_template/cookiecutter.json +17 -0
  44. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/__init__.py +13 -0
  45. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/clean.py +23 -0
  46. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/config.yaml.example +2 -0
  47. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/deploy.py +41 -0
  48. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/Dockerfile +23 -0
  49. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/app.py +123 -0
  50. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/init_db.py +46 -0
  51. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/models.py +36 -0
  52. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/requirements.txt +4 -0
  53. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/run.sh +21 -0
  54. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/css/style.css +368 -0
  55. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/js/admin.js +0 -0
  56. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/dashboard.html +21 -0
  57. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/edit_post.html +24 -0
  58. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/login.html +21 -0
  59. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/posts.html +53 -0
  60. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/base.html +45 -0
  61. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/index.html +29 -0
  62. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/post.html +14 -0
  63. veadk/integrations/ve_prompt_pilot/ve_prompt_pilot.py +6 -3
  64. veadk/integrations/ve_tls/__init__.py +13 -0
  65. veadk/integrations/ve_tls/utils.py +117 -0
  66. veadk/integrations/ve_tls/ve_tls.py +208 -0
  67. veadk/integrations/ve_tos/ve_tos.py +128 -73
  68. veadk/knowledgebase/knowledgebase.py +116 -20
  69. veadk/memory/long_term_memory.py +20 -21
  70. veadk/memory/short_term_memory_processor.py +9 -4
  71. veadk/runner.py +213 -223
  72. veadk/tools/builtin_tools/vesearch.py +2 -2
  73. veadk/tools/builtin_tools/video_generate.py +27 -20
  74. veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +5 -0
  75. veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py +253 -129
  76. veadk/tracing/telemetry/attributes/extractors/types.py +15 -4
  77. veadk/tracing/telemetry/exporters/apmplus_exporter.py +158 -12
  78. veadk/tracing/telemetry/exporters/cozeloop_exporter.py +4 -9
  79. veadk/tracing/telemetry/exporters/tls_exporter.py +4 -10
  80. veadk/tracing/telemetry/opentelemetry_tracer.py +11 -5
  81. veadk/tracing/telemetry/telemetry.py +23 -5
  82. veadk/utils/logger.py +1 -1
  83. veadk/utils/misc.py +48 -0
  84. veadk/utils/volcengine_sign.py +6 -2
  85. veadk/version.py +1 -1
  86. {veadk_python-0.2.5.dist-info → veadk_python-0.2.7.dist-info}/METADATA +2 -1
  87. veadk_python-0.2.7.dist-info/RECORD +172 -0
  88. veadk_python-0.2.5.dist-info/RECORD +0 -127
  89. /veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{{ cookiecutter.app_name|replace('-', '_') }} → {{ cookiecutter.app_name }}}/__init__.py +0 -0
  90. /veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{{ cookiecutter.app_name|replace('-', '_') }} → {{ cookiecutter.app_name }}}/agent.py +0 -0
  91. {veadk_python-0.2.5.dist-info → veadk_python-0.2.7.dist-info}/WHEEL +0 -0
  92. {veadk_python-0.2.5.dist-info → veadk_python-0.2.7.dist-info}/entry_points.txt +0 -0
  93. {veadk_python-0.2.5.dist-info → veadk_python-0.2.7.dist-info}/licenses/LICENSE +0 -0
  94. {veadk_python-0.2.5.dist-info → veadk_python-0.2.7.dist-info}/top_level.txt +0 -0
@@ -38,9 +38,12 @@ create_collection_path = "/api/knowledge/collection/create"
38
38
  search_knowledge_path = "/api/knowledge/collection/search_knowledge"
39
39
  list_collections_path = "/api/knowledge/collection/list"
40
40
  get_collections_path = "/api/knowledge/collection/info"
41
+ doc_del_path = "/api/knowledge/collection/delete"
41
42
  doc_add_path = "/api/knowledge/doc/add"
42
43
  doc_info_path = "/api/knowledge/doc/info"
43
- doc_del_path = "/api/collection/drop"
44
+ list_point_path = "/api/knowledge/point/list"
45
+ list_docs_path = "/api/knowledge/doc/list"
46
+ delete_docs_path = "/api/knowledge/doc/delete"
44
47
 
45
48
 
46
49
  class VolcengineTOSConfig(BaseModel):
@@ -134,11 +137,25 @@ class VikingDatabase(BaseModel, BaseDatabase):
134
137
  self,
135
138
  data: str | list[str] | TextIO | BinaryIO | bytes,
136
139
  **kwargs: Any,
137
- ):
138
- file_ext = kwargs.get(
139
- "file_ext", ".pdf"
140
- ) # when bytes data, file_ext is required
140
+ ) -> tuple[int, str]:
141
+ """
142
+ Upload data to TOS (Tinder Object Storage).
141
143
 
144
+ Args:
145
+ data: The data to be uploaded. Can be one of the following types:
146
+ - str: File path or string data
147
+ - list[str]: List of strings
148
+ - TextIO: File object (text)
149
+ - BinaryIO: File object (binary)
150
+ - bytes: Binary data
151
+ **kwargs: Additional keyword arguments.
152
+ - file_name (str): The file name (including suffix).
153
+
154
+ Returns:
155
+ tuple: A tuple containing the status code and TOS URL.
156
+ - status_code (int): HTTP status code
157
+ - tos_url (str): The URL of the uploaded file in TOS
158
+ """
142
159
  ak = self.config.volcengine_ak
143
160
  sk = self.config.volcengine_sk
144
161
 
@@ -149,21 +166,31 @@ class VikingDatabase(BaseModel, BaseDatabase):
149
166
 
150
167
  client = tos.TosClientV2(ak, sk, tos_endpoint, tos_region, max_connections=1024)
151
168
 
169
+ # Extract file_name from kwargs - this is now required and includes the extension
170
+ file_names = kwargs.get("file_name")
171
+
152
172
  if isinstance(data, str) and os.path.isfile(data): # Process file path
153
- file_ext = os.path.splitext(data)[1]
154
- new_key = f"{tos_key}/{str(uuid.uuid4())}{file_ext}"
173
+ # Use provided file_name which includes the extension
174
+ new_key = f"{tos_key}/{file_names}"
155
175
  with open(data, "rb") as f:
156
176
  upload_data = f.read()
157
177
 
178
+ elif (
179
+ isinstance(data, list)
180
+ and all(isinstance(item, str) for item in data)
181
+ and all(os.path.isfile(item) for item in data)
182
+ ):
183
+ # Process list of file paths - this should be handled at a higher level
184
+ raise ValueError(
185
+ "Uploading multiple files through a list of file paths is not supported in _upload_to_tos directly. Please call this function for each file individually."
186
+ )
187
+
158
188
  elif isinstance(
159
189
  data,
160
190
  (io.TextIOWrapper, io.BufferedReader), # file type: TextIO | BinaryIO
161
191
  ): # Process file stream
162
- # Try to get the file extension from the file name, and use the default value if there is none
163
- file_ext = ".unknown"
164
- if hasattr(data, "name"):
165
- _, file_ext = os.path.splitext(data.name)
166
- new_key = f"{tos_key}/{str(uuid.uuid4())}{file_ext}"
192
+ # Use provided file_name which includes the extension
193
+ new_key = f"{tos_key}/{file_names}"
167
194
  if isinstance(data, TextIO):
168
195
  # Encode the text stream content into bytes
169
196
  upload_data = data.read().encode("utf-8")
@@ -172,16 +199,19 @@ class VikingDatabase(BaseModel, BaseDatabase):
172
199
  upload_data = data.read()
173
200
 
174
201
  elif isinstance(data, str): # Process ordinary strings
175
- new_key = f"{tos_key}/{str(uuid.uuid4())}.txt"
202
+ # Use provided file_name which includes the extension
203
+ new_key = f"{tos_key}/{file_names}"
176
204
  upload_data = data.encode("utf-8") # Encode as byte type
177
205
 
178
206
  elif isinstance(data, list): # Process list of strings
179
- new_key = f"{tos_key}/{str(uuid.uuid4())}.txt"
207
+ # Use provided file_name which includes the extension
208
+ new_key = f"{tos_key}/{file_names}"
180
209
  # Join the strings in the list with newlines and encode as byte type
181
210
  upload_data = "\n".join(data).encode("utf-8")
182
211
 
183
212
  elif isinstance(data, bytes): # Process bytes data
184
- new_key = f"{tos_key}/{str(uuid.uuid4())}{file_ext}"
213
+ # Use provided file_name which includes the extension
214
+ new_key = f"{tos_key}/{file_names}"
185
215
  upload_data = data
186
216
 
187
217
  else:
@@ -229,33 +259,141 @@ class VikingDatabase(BaseModel, BaseDatabase):
229
259
  **kwargs,
230
260
  ):
231
261
  """
262
+ Add documents to the Viking database.
232
263
  Args:
233
- data: str, file path or file stream: Both file or file.read() are acceptable.
234
- **kwargs: collection_name(required)
264
+ data: The data to be added. Can be one of the following types:
265
+ - str: File path or string data
266
+ - list[str]: List of file paths or list of strings
267
+ - TextIO: File object (text)
268
+ - BinaryIO: File object (binary)
269
+ - bytes: Binary data
270
+ collection_name: The name of the collection to add documents to.
271
+ **kwargs: Additional keyword arguments.
272
+ - file_name (str | list[str]): The file name or a list of file names (including suffix).
273
+ - doc_id (str): The document ID. If not provided, a UUID will be generated.
235
274
  Returns:
236
- {
275
+ dict or list: A dictionary containing the TOS URL and document ID, or a list of such dictionaries for multiple file uploads.
276
+ Format: {
237
277
  "tos_url": "tos://<bucket>/<key>",
238
278
  "doc_id": "<doc_id>",
239
279
  }
240
280
  """
241
-
242
- status, tos_url = self._upload_to_tos(data=data, **kwargs)
243
- if status != 200:
244
- raise ValueError(f"Error in upload_to_tos: {status}")
245
- doc_id = self._add_doc(
246
- collection_name=collection_name,
247
- tos_url=tos_url,
248
- doc_id=str(uuid.uuid4()),
249
- )
250
- return {
251
- "tos_url": f"tos://{tos_url}",
252
- "doc_id": doc_id,
253
- }
281
+ # Handle list of file paths (multiple file upload)
282
+ if (
283
+ isinstance(data, list)
284
+ and all(isinstance(item, str) for item in data)
285
+ and all(os.path.isfile(item) for item in data)
286
+ ):
287
+ # Handle multiple file upload
288
+ file_names = kwargs.get("file_name")
289
+ if (
290
+ not file_names
291
+ or not isinstance(file_names, list)
292
+ or len(file_names) != len(data)
293
+ ):
294
+ raise ValueError(
295
+ "For multiple file upload, file_name must be provided as a list with the same length as data"
296
+ )
297
+
298
+ results = []
299
+ for i, file_path in enumerate(data):
300
+ # Create kwargs for this specific file
301
+ single_kwargs = kwargs.copy()
302
+ single_kwargs["file_name"] = file_names[i]
303
+
304
+ # Generate or use provided doc_id for this file
305
+ doc_id = single_kwargs.get("doc_id")
306
+ if not doc_id:
307
+ doc_id = str(uuid.uuid4())
308
+ single_kwargs["doc_id"] = doc_id
309
+
310
+ status, tos_url = self._upload_to_tos(data=file_path, **single_kwargs)
311
+ if status != 200:
312
+ raise ValueError(
313
+ f"Error in upload_to_tos for file {file_path}: {status}"
314
+ )
315
+
316
+ doc_id = self._add_doc(
317
+ collection_name=collection_name,
318
+ tos_url=tos_url,
319
+ doc_id=doc_id,
320
+ )
321
+
322
+ results.append(
323
+ {
324
+ "tos_url": f"tos://{tos_url}",
325
+ "doc_id": doc_id,
326
+ }
327
+ )
328
+
329
+ return results
330
+
331
+ # Handle list of strings (multiple string upload)
332
+ elif isinstance(data, list) and all(isinstance(item, str) for item in data):
333
+ # Handle multiple string upload
334
+ file_names = kwargs.get("file_name")
335
+ if (
336
+ not file_names
337
+ or not isinstance(file_names, list)
338
+ or len(file_names) != len(data)
339
+ ):
340
+ raise ValueError(
341
+ "For multiple string upload, file_name must be provided as a list with the same length as data"
342
+ )
343
+
344
+ results = []
345
+ for i, content in enumerate(data):
346
+ # Create kwargs for this specific string
347
+ single_kwargs = kwargs.copy()
348
+ single_kwargs["file_name"] = file_names[i]
349
+
350
+ # Generate or use provided doc_id for this string
351
+ doc_id = single_kwargs.get("doc_id")
352
+ if not doc_id:
353
+ doc_id = str(uuid.uuid4())
354
+ single_kwargs["doc_id"] = doc_id
355
+
356
+ status, tos_url = self._upload_to_tos(data=content, **single_kwargs)
357
+ if status != 200:
358
+ raise ValueError(f"Error in upload_to_tos for string {i}: {status}")
359
+
360
+ doc_id = self._add_doc(
361
+ collection_name=collection_name,
362
+ tos_url=tos_url,
363
+ doc_id=doc_id,
364
+ )
365
+
366
+ results.append(
367
+ {
368
+ "tos_url": f"tos://{tos_url}",
369
+ "doc_id": doc_id,
370
+ }
371
+ )
372
+
373
+ return results
374
+
375
+ # Handle single file upload or other data types
376
+ else:
377
+ # Handle doc_id from kwargs or generate a new one
378
+ doc_id = kwargs.get("doc_id", str(uuid.uuid4()))
379
+
380
+ status, tos_url = self._upload_to_tos(data=data, **kwargs)
381
+ if status != 200:
382
+ raise ValueError(f"Error in upload_to_tos: {status}")
383
+ doc_id = self._add_doc(
384
+ collection_name=collection_name,
385
+ tos_url=tos_url,
386
+ doc_id=doc_id,
387
+ )
388
+ return {
389
+ "tos_url": f"tos://{tos_url}",
390
+ "doc_id": doc_id,
391
+ }
254
392
 
255
393
  def delete(self, **kwargs: Any):
256
- collection_name = kwargs.get("collection_name")
257
- resource_id = kwargs.get("resource_id")
258
- request_param = {"collection_name": collection_name, "resource_id": resource_id}
394
+ name = kwargs.get("name")
395
+ project = kwargs.get("project", self.config.project)
396
+ request_param = {"name": name, "project": project}
259
397
  doc_del_req = prepare_request(
260
398
  method="POST", path=doc_del_path, config=self.config, data=request_param
261
399
  )
@@ -268,8 +406,8 @@ class VikingDatabase(BaseModel, BaseDatabase):
268
406
  result = rsp.json()
269
407
  if result["code"] != 0:
270
408
  logger.error(f"Error in add_doc: {result['message']}")
271
- return {"error": result["message"]}
272
- return {}
409
+ return False
410
+ return True
273
411
 
274
412
  def query(self, query: str, **kwargs: Any) -> list[str]:
275
413
  """
@@ -400,3 +538,101 @@ class VikingDatabase(BaseModel, BaseDatabase):
400
538
  return True
401
539
  else:
402
540
  return False
541
+
542
+ def list_chunks(
543
+ self, collection_name: str, offset: int = 0, limit: int = -1
544
+ ) -> list[dict]:
545
+ request_params = {
546
+ "collection_name": collection_name,
547
+ "project": self.config.project,
548
+ "offset": offset,
549
+ "limit": limit,
550
+ }
551
+
552
+ list_doc_req = prepare_request(
553
+ method="POST",
554
+ path=list_point_path,
555
+ config=self.config,
556
+ data=request_params,
557
+ )
558
+ resp = requests.request(
559
+ method=list_doc_req.method,
560
+ url="https://{}{}".format(g_knowledge_base_domain, list_doc_req.path),
561
+ headers=list_doc_req.headers,
562
+ data=list_doc_req.body,
563
+ )
564
+
565
+ result = resp.json()
566
+ if result["code"] != 0:
567
+ logger.error(f"Error in list_docs: {result['message']}")
568
+ raise ValueError(f"Error in list_docs: {result['message']}")
569
+
570
+ if not result["data"].get("point_list", []):
571
+ return []
572
+
573
+ data = [
574
+ {
575
+ "id": res["point_id"],
576
+ "content": res["content"],
577
+ "metadata": res["doc_info"],
578
+ }
579
+ for res in result["data"]["point_list"]
580
+ ]
581
+ return data
582
+
583
+ def list_docs(
584
+ self, collection_name: str, offset: int = 0, limit: int = -1
585
+ ) -> list[dict]:
586
+ request_params = {
587
+ "collection_name": collection_name,
588
+ "project": self.config.project,
589
+ "offset": offset,
590
+ "limit": limit,
591
+ }
592
+
593
+ list_doc_req = prepare_request(
594
+ method="POST",
595
+ path=list_docs_path,
596
+ config=self.config,
597
+ data=request_params,
598
+ )
599
+ resp = requests.request(
600
+ method=list_doc_req.method,
601
+ url="https://{}{}".format(g_knowledge_base_domain, list_doc_req.path),
602
+ headers=list_doc_req.headers,
603
+ data=list_doc_req.body,
604
+ )
605
+
606
+ result = resp.json()
607
+ if result["code"] != 0:
608
+ logger.error(f"Error in list_docs: {result['message']}")
609
+ raise ValueError(f"Error in list_docs: {result['message']}")
610
+
611
+ if not result["data"].get("doc_list", []):
612
+ return []
613
+ return result["data"]["doc_list"]
614
+
615
+ def delete_by_id(self, collection_name: str, id: str) -> bool:
616
+ request_params = {
617
+ "collection_name": collection_name,
618
+ "project": self.config.project,
619
+ "doc_id": id,
620
+ }
621
+
622
+ delete_by_id_req = prepare_request(
623
+ method="POST",
624
+ path=delete_docs_path,
625
+ config=self.config,
626
+ data=request_params,
627
+ )
628
+ resp = requests.request(
629
+ method=delete_by_id_req.method,
630
+ url="https://{}{}".format(g_knowledge_base_domain, delete_by_id_req.path),
631
+ headers=delete_by_id_req.headers,
632
+ data=delete_by_id_req.body,
633
+ )
634
+
635
+ result = resp.json()
636
+ if result["code"] != 0:
637
+ return False
638
+ return True
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.