davidkhala.ai 0.2.0__py3-none-any.whl → 0.2.2__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.
Files changed (57) hide show
  1. davidkhala/ai/agent/dify/api/__init__.py +2 -2
  2. davidkhala/ai/agent/dify/api/app.py +10 -6
  3. davidkhala/ai/agent/dify/api/knowledge/__init__.py +0 -0
  4. davidkhala/ai/agent/dify/api/knowledge/chunk.py +14 -0
  5. davidkhala/ai/agent/dify/api/knowledge/dataset.py +82 -0
  6. davidkhala/ai/agent/dify/api/knowledge/document.py +42 -0
  7. davidkhala/ai/agent/dify/api/knowledge/model.py +139 -0
  8. davidkhala/ai/agent/dify/{ops/console → console}/__init__.py +7 -1
  9. davidkhala/ai/agent/dify/console/knowledge/__init__.py +0 -0
  10. davidkhala/ai/agent/dify/console/knowledge/dataset.py +61 -0
  11. davidkhala/ai/agent/dify/console/knowledge/pipeline.py +127 -0
  12. davidkhala/ai/agent/dify/{ops/console → console}/plugin.py +21 -7
  13. davidkhala/ai/agent/dify/console/session.py +50 -0
  14. davidkhala/ai/agent/dify/db/orm.py +65 -0
  15. davidkhala/ai/agent/dify/model/__init__.py +7 -0
  16. davidkhala/ai/agent/dify/{model.py → model/knowledge.py} +1 -12
  17. davidkhala/ai/agent/dify/{ops/db/orm.py → model/workflow.py} +24 -62
  18. davidkhala/ai/agent/dify/plugins/popular.py +4 -1
  19. davidkhala/ai/agent/langgraph.py +1 -1
  20. davidkhala/ai/ali/dashscope.py +15 -18
  21. davidkhala/ai/anthropic/__init__.py +6 -0
  22. davidkhala/ai/api/__init__.py +6 -18
  23. davidkhala/ai/api/openrouter.py +14 -10
  24. davidkhala/ai/api/siliconflow.py +2 -4
  25. davidkhala/ai/atlas/__init__.py +24 -0
  26. davidkhala/ai/mistral/__init__.py +15 -0
  27. davidkhala/ai/mistral/agent.py +50 -0
  28. davidkhala/ai/mistral/ai.py +40 -0
  29. davidkhala/ai/mistral/file.py +38 -0
  30. davidkhala/ai/mistral/ocr.py +46 -0
  31. davidkhala/ai/model/__init__.py +28 -0
  32. davidkhala/ai/model/chat.py +75 -0
  33. davidkhala/ai/model/embed.py +8 -0
  34. davidkhala/ai/model/garden.py +9 -0
  35. davidkhala/ai/openai/__init__.py +24 -40
  36. davidkhala/ai/openai/azure.py +55 -3
  37. davidkhala/ai/openai/databricks.py +23 -0
  38. davidkhala/ai/openai/native.py +4 -4
  39. davidkhala/ai/openai/opik.py +10 -0
  40. davidkhala/ai/openrouter/__init__.py +25 -13
  41. davidkhala/ai/you.py +55 -0
  42. {davidkhala_ai-0.2.0.dist-info → davidkhala_ai-0.2.2.dist-info}/METADATA +12 -6
  43. davidkhala_ai-0.2.2.dist-info/RECORD +65 -0
  44. davidkhala/ai/agent/dify/api/knowledge.py +0 -191
  45. davidkhala/ai/agent/dify/ops/__init__.py +0 -1
  46. davidkhala/ai/agent/dify/ops/console/knowledge.py +0 -158
  47. davidkhala/ai/agent/dify/ops/console/session.py +0 -32
  48. davidkhala/ai/huggingface/BAAI.py +0 -10
  49. davidkhala/ai/huggingface/__init__.py +0 -21
  50. davidkhala/ai/huggingface/inference.py +0 -13
  51. davidkhala/ai/model.py +0 -28
  52. davidkhala_ai-0.2.0.dist-info/RECORD +0 -48
  53. /davidkhala/ai/agent/dify/{ops/db → db}/__init__.py +0 -0
  54. /davidkhala/ai/agent/dify/{ops/db → db}/app.py +0 -0
  55. /davidkhala/ai/agent/dify/{ops/db → db}/knowledge.py +0 -0
  56. /davidkhala/ai/agent/dify/{ops/db → db}/sys.py +0 -0
  57. {davidkhala_ai-0.2.0.dist-info → davidkhala_ai-0.2.2.dist-info}/WHEEL +0 -0
@@ -0,0 +1,28 @@
1
+ from typing import Protocol, Any
2
+
3
+
4
+ class ClientProtocol(Protocol):
5
+ api_key: str
6
+ base_url: str
7
+
8
+
9
+ class ModelAware:
10
+ def __init__(self):
11
+ self.model: str | None = None
12
+
13
+
14
+ class SDKProtocol(Protocol):
15
+ client: Any
16
+
17
+
18
+ class Connectable:
19
+ def connect(self) -> bool: ...
20
+
21
+ def close(self): ...
22
+
23
+ def __enter__(self):
24
+ assert self.connect()
25
+ return self
26
+
27
+ def __exit__(self, exc_type, exc_val, exc_tb):
28
+ self.close()
@@ -0,0 +1,75 @@
1
+ from typing import Protocol, Any, Iterable, TypedDict
2
+
3
+ from davidkhala.ai.model import ModelAware
4
+
5
+
6
+ class MessageProtocol(Protocol):
7
+ content: str | Any
8
+
9
+
10
+ class ChoiceProtocol(Protocol):
11
+ message: MessageProtocol
12
+
13
+
14
+ class ChoicesAware(Protocol):
15
+ choices: list[ChoiceProtocol]
16
+
17
+
18
+ class ImagePromptDict(TypedDict):
19
+ text: str
20
+ image_url: list[str]
21
+
22
+
23
+ def on_response(response: ChoicesAware, n: int | None):
24
+ contents = [choice.message.content for choice in response.choices]
25
+ if n:
26
+ assert len(contents) == n, f"expected {n} choices, but got {len(contents)}"
27
+ return contents
28
+
29
+
30
+ class MessageDict(TypedDict):
31
+ content: str | list | None
32
+ role: str
33
+
34
+
35
+ def messages_from(*user_prompt: str | ImagePromptDict) -> Iterable[MessageDict]:
36
+ for _ in user_prompt:
37
+ message = MessageDict(role='user', content=None)
38
+ if type(_) == str:
39
+ message['content'] = _
40
+ elif type(_) == dict:
41
+ message['content'] = [{"type": "text", "text": _['text']}]
42
+ message['content'].extend({"type": "image_url", "image_url": {"url": i}} for i in _['image_url'])
43
+ yield message
44
+
45
+
46
+ class ChatAware(ModelAware):
47
+ def __init__(self):
48
+ super().__init__()
49
+ self.messages: list[Any | MessageDict] = []
50
+ self.n: int = 1
51
+
52
+ def as_chat(self, model: str | None, sys_prompt: str = None):
53
+ self.model = model
54
+ if sys_prompt is not None:
55
+ self.messages = [MessageDict(role='system', content=sys_prompt)]
56
+
57
+ def chat(self, *user_prompt, **kwargs): ...
58
+
59
+ def messages_from(self, *user_prompt) -> list[MessageDict]:
60
+ messages = list(self.messages)
61
+ messages.extend(messages_from(*user_prompt))
62
+ return messages
63
+
64
+
65
+ class CompareChatAware(ChatAware):
66
+ def __init__(self):
67
+ super().__init__()
68
+ self._models = None
69
+
70
+ def as_chat(self, *models: str, sys_prompt: str = None):
71
+ if len(models) > 1:
72
+ self._models = models
73
+ super().as_chat(None, sys_prompt)
74
+ elif len(models) == 1:
75
+ super().as_chat(models[0], sys_prompt)
@@ -0,0 +1,8 @@
1
+ from davidkhala.ai.model import ModelAware
2
+
3
+
4
+ class EmbeddingAware(ModelAware):
5
+ def as_embeddings(self, model: str):
6
+ self.model = model
7
+
8
+ def encode(self, *_input: str) -> list[list[float]]: ...
@@ -0,0 +1,9 @@
1
+ from typing import Protocol
2
+
3
+
4
+ class GardenAlike(Protocol):
5
+ @property
6
+ def models(self) -> list[str]: ...
7
+
8
+ @property
9
+ def free_models(self) -> list[str]: ...
@@ -1,18 +1,29 @@
1
- import runpy
2
- from typing import Union, Literal
1
+ from typing import Literal
3
2
 
4
- from openai import OpenAI, AsyncOpenAI
3
+ from openai import OpenAI
5
4
 
6
- from davidkhala.ai.model import AbstractClient
5
+ from davidkhala.ai.model import SDKProtocol, Connectable
6
+ from davidkhala.ai.model.embed import EmbeddingAware
7
+ from davidkhala.ai.model.chat import on_response, ChatAware
8
+ from davidkhala.ai.model.garden import GardenAlike
7
9
 
8
10
 
9
- class Client(AbstractClient):
10
- client: OpenAI
11
- encoding_format: Literal["float", "base64"] = "float"
12
- n = 1
11
+ class Client(ChatAware, EmbeddingAware, SDKProtocol, GardenAlike, Connectable):
12
+ def __init__(self, client: OpenAI):
13
+ super().__init__()
14
+ self.client: OpenAI = client
15
+ self.encoding_format: Literal["float", "base64"] = "float"
13
16
 
14
17
  def connect(self):
15
- self.client.models.list()
18
+ try:
19
+ type(self).models.fget(self)
20
+ return True
21
+ except: # TODO make specific
22
+ return False
23
+
24
+ @property
25
+ def models(self):
26
+ return self.client.models.list()
16
27
 
17
28
  def encode(self, *_input: str) -> list[list[float]]:
18
29
  response = self.client.embeddings.create(
@@ -24,41 +35,14 @@ class Client(AbstractClient):
24
35
 
25
36
  def chat(self, *user_prompt, **kwargs):
26
37
 
27
- messages = [
28
- *self.messages,
29
- ]
30
- for prompt in user_prompt:
31
- message = {
32
- "role": "user"
33
- }
34
- if type(prompt) == str:
35
- message['content'] = prompt
36
- elif type(prompt) == dict:
37
- message['content'] = [
38
- {"type": "text", "text": prompt['text']},
39
- {
40
- "type": "image_url",
41
- "image_url": {
42
- "url": prompt['image_url'],
43
- }
44
- },
45
- ]
46
- messages.append(message)
47
38
  response = self.client.chat.completions.create(
48
39
  model=self.model,
49
- messages=messages,
40
+ messages=self.messages_from(*user_prompt),
50
41
  n=self.n,
51
42
  **kwargs
52
43
  )
53
- contents = [choice.message.content for choice in response.choices]
54
- assert len(contents) == self.n
55
- return contents
56
-
57
- def disconnect(self):
58
- self.client.close()
59
44
 
45
+ return on_response(response, self.n)
60
46
 
61
- def with_opik(instance: Union[OpenAI, AsyncOpenAI]):
62
- from opik.integrations.openai import track_openai
63
- runpy.run_path('../opik.py')
64
- return track_openai(instance)
47
+ def close(self):
48
+ self.client.close()
@@ -1,6 +1,18 @@
1
+ import base64
2
+ import json
3
+ from pathlib import Path
4
+
5
+ from davidkhala.ml.ocr.interface import FieldProperties
1
6
  from davidkhala.utils.syntax.compat import deprecated
2
7
  from openai import AzureOpenAI, OpenAI
8
+ from openai.types.chat import (
9
+ ChatCompletionUserMessageParam, ChatCompletionContentPartTextParam, ChatCompletionContentPartImageParam
10
+ )
11
+ from openai.types.chat.chat_completion_content_part_image_param import ImageURL
12
+ from openai.types.shared_params import ResponseFormatJSONSchema
13
+ from openai.types.shared_params.response_format_json_schema import JSONSchema
3
14
 
15
+ from davidkhala.ai.model.chat import on_response
4
16
  from davidkhala.ai.openai import Client
5
17
 
6
18
 
@@ -10,23 +22,63 @@ class AzureHosted(Client):
10
22
  raise ValueError('Web search options not supported in any models of Azure AI Foundry')
11
23
  return super().chat(*user_prompt, **kwargs)
12
24
 
25
+
13
26
  class ModelDeploymentClient(AzureHosted):
14
27
  def __init__(self, key, deployment):
15
- self.client = AzureOpenAI(
28
+ super().__init__(AzureOpenAI(
16
29
  api_version="2024-12-01-preview", # mandatory
17
30
  azure_endpoint=f"https://{deployment}.cognitiveservices.azure.com/",
18
31
  api_key=key,
32
+ ))
33
+
34
+ def process(self, file: Path, schema: dict[str, FieldProperties])-> list[dict]:
35
+ with open(file, "rb") as f:
36
+ content = base64.b64encode(f.read()).decode("utf-8")
37
+ required = [k for k, _ in schema.items() if _.required]
38
+ properties = {k: {'type': v.type} for k, v in schema.items()}
39
+
40
+ json_schema = JSONSchema(
41
+ name='-',
42
+ schema={"type": "object",
43
+ "properties": properties,
44
+ "required": required,
45
+ },
19
46
  )
20
47
 
48
+ self.messages.append(ChatCompletionUserMessageParam(
49
+ role='user',
50
+ content=[
51
+ ChatCompletionContentPartTextParam(
52
+ type='text',
53
+ text="Extract the required fields from this image and return the output strictly following the provided JSON schema."),
54
+ ChatCompletionContentPartImageParam(
55
+ type="image_url",
56
+ image_url=ImageURL(
57
+ url=f"data:image/jpeg;base64,{content}",
58
+ detail='auto'
59
+ )
60
+ )
61
+ ]
62
+ ))
63
+ response = self.client.chat.completions.create(
64
+ model=self.model,
65
+ messages=self.messages,
66
+ response_format=ResponseFormatJSONSchema(
67
+ type='json_schema',
68
+ json_schema=json_schema
69
+ ),
70
+ n=self.n,
71
+ )
72
+ return [json.loads(_) for _ in on_response(response, self.n)]
21
73
 
22
74
  @deprecated("Azure Open AI is deprecated. Please migrate to Microsoft Foundry")
23
75
  class OpenAIClient(AzureHosted):
24
76
 
25
77
  def __init__(self, api_key, project):
26
- self.client = OpenAI(
78
+ super().__init__(OpenAI(
27
79
  base_url=f"https://{project}.openai.azure.com/openai/v1/",
28
80
  api_key=api_key,
29
- )
81
+ ))
30
82
 
31
83
  def as_chat(self, model="gpt-oss-120b", sys_prompt: str = None):
32
84
  super().as_chat(model, sys_prompt)
@@ -0,0 +1,23 @@
1
+ from openai import OpenAI
2
+ from davidkhala.ai.openai import Client as BaseClient
3
+
4
+
5
+ class Client(BaseClient):
6
+ def __init__(self, host: str, token: str):
7
+ super().__init__(OpenAI(
8
+ base_url=f"https://{host}/serving-endpoints",
9
+ api_key=token
10
+ ))
11
+
12
+ def chat(self, *user_prompt, **kwargs):
13
+ """Databricks always reasoning"""
14
+ rs = super().chat(*user_prompt, **kwargs)
15
+ for r in rs:
16
+ assert len(r) == 2
17
+ assert r[0]['type'] == 'reasoning'
18
+ for s in r[0]['summary']:
19
+ assert s['type'] =='summary_text'
20
+ yield s['text']
21
+ assert r[1]['type'] == 'text'
22
+ yield r[1]['text']
23
+
@@ -1,4 +1,4 @@
1
- from typing import Optional, Literal
1
+ from typing import Literal
2
2
 
3
3
  from openai import OpenAI
4
4
 
@@ -7,12 +7,12 @@ from davidkhala.ai.openai import Client
7
7
 
8
8
  class NativeClient(Client):
9
9
  def __init__(self, api_key, base_url=None):
10
- self.client = OpenAI(
10
+ super().__init__(OpenAI(
11
11
  api_key=api_key,
12
12
  base_url=base_url
13
- )
13
+ ))
14
14
 
15
- def chat(self, *user_prompt, web_search:Optional[Literal["low", "medium", "high"]]=None, **kwargs):
15
+ def chat(self, *user_prompt, web_search: Literal["low", "medium", "high"] = None, **kwargs):
16
16
  opts = {
17
17
  **kwargs
18
18
  }
@@ -0,0 +1,10 @@
1
+ import runpy
2
+
3
+ from openai import OpenAI, AsyncOpenAI
4
+ from typing import Union
5
+
6
+
7
+ def bind(instance: Union[OpenAI, AsyncOpenAI]):
8
+ from opik.integrations.openai import track_openai
9
+ runpy.run_path('../opik.py')
10
+ return track_openai(instance)
@@ -1,35 +1,47 @@
1
+ from openrouter import OpenRouter
2
+ from openrouter.components import Model
1
3
  from openrouter.errors import UnauthorizedResponseError
4
+ from openrouter.operations import ListData
2
5
 
3
- from davidkhala.ai.model import AbstractClient
4
- from openrouter import OpenRouter
6
+ from davidkhala.ai.model import Connectable, SDKProtocol
7
+ from davidkhala.ai.model.chat import CompareChatAware, on_response
8
+ from davidkhala.ai.model.garden import GardenAlike
5
9
 
6
10
 
7
- class Client(AbstractClient):
11
+ class Client(CompareChatAware, Connectable, SDKProtocol, GardenAlike):
8
12
  def __init__(self, api_key: str):
9
- self.api_key = api_key
10
- self.client = OpenRouter(api_key)
13
+ super().__init__()
14
+ self.client: OpenRouter = OpenRouter(api_key)
11
15
 
12
16
  def chat(self, *user_prompt, **kwargs):
13
17
  r = self.client.chat.send(
14
18
  model=self.model,
15
- messages=[
16
- *self.messages,
17
- *[{'role': 'user', 'content': _} for _ in user_prompt]
18
- ]
19
+ models=self._models,
20
+ messages=self.messages_from(*user_prompt)
21
+ # openrouter has no n
19
22
  )
20
- return [_.message.content for _ in r.choices]
23
+ return on_response(r, None)
24
+
21
25
  def connect(self):
22
26
  try:
23
- self.client.models.list()
27
+ _ = self.models
24
28
  return True
25
29
  except UnauthorizedResponseError:
26
30
  return False
27
31
 
32
+ def list_models(self) -> list[Model]:
33
+ return self.client.models.list().data
34
+
35
+ @property
36
+ def models(self) -> list[str]:
37
+ return [m.id for m in self.list_models()]
38
+
28
39
 
29
40
  class Admin:
30
41
  def __init__(self, provisioning_key: str):
31
42
  self.provisioning_key = provisioning_key
32
43
  self.client = OpenRouter(provisioning_key)
44
+
33
45
  @property
34
- def keys(self):
35
- return self.client.api_keys.list().data
46
+ def keys(self) -> list[ListData]:
47
+ return self.client.api_keys.list().data
davidkhala/ai/you.py ADDED
@@ -0,0 +1,55 @@
1
+ from typing import AsyncIterator
2
+
3
+ from youdotcom import You, models
4
+ from youdotcom.models import Web
5
+ from youdotcom.types.typesafe_models import AgentType, get_text_tokens, Format
6
+ from youdotcom.utils import eventstreaming
7
+
8
+
9
+ class Client:
10
+ def __init__(self, api_key: str):
11
+ self.client = You(api_key_auth=api_key)
12
+
13
+ def chat(self, user_prompt: str, *, tools: list[models.Tool] = None) -> str:
14
+ res = self.client.agents.runs.create(
15
+ agent=AgentType.ADVANCED if tools else AgentType.EXPRESS,
16
+ input=user_prompt,
17
+ stream=False,
18
+ tools=tools,
19
+ )
20
+
21
+ return "".join(get_text_tokens(res))
22
+
23
+ def scrape(self, *urls: str) -> list[str]:
24
+ """
25
+ :return the content of the web pages as Markdown format (incl. metadata)
26
+ """
27
+ res = self.client.contents.generate(
28
+ urls=list(urls),
29
+ format_=Format.MARKDOWN,
30
+ )
31
+ return [_.markdown for _ in res]
32
+
33
+ def search(self, query: str) -> list[Web]:
34
+ res = self.client.search.unified(
35
+ query=query
36
+ )
37
+ return res.results.web
38
+
39
+ async def async_chat(self, user_prompt: str) -> AsyncIterator[str]:
40
+ res: eventstreaming.EventStreamAsync[models.Data] = await self.client.agents.runs.create_async(
41
+ agent=AgentType.EXPRESS,
42
+ input=user_prompt,
43
+ stream=True,
44
+ )
45
+
46
+ async for event in res:
47
+ if event.type == 'response.output_text.delta':
48
+ yield event.response.delta
49
+
50
+ def __enter__(self):
51
+ self.client.__enter__()
52
+ return self
53
+
54
+ def __exit__(self, exc_type, exc_val, exc_tb):
55
+ self.client.close()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: davidkhala.ai
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: misc AI modules
5
5
  Requires-Python: >=3.12
6
6
  Provides-Extra: ali
@@ -9,7 +9,10 @@ Requires-Dist: davidkhala-utils; extra == 'ali'
9
9
  Requires-Dist: wuying-agentbay-sdk; extra == 'ali'
10
10
  Provides-Extra: api
11
11
  Requires-Dist: davidkhala-utils[http-request]; extra == 'api'
12
+ Provides-Extra: atlas
13
+ Requires-Dist: voyageai; extra == 'atlas'
12
14
  Provides-Extra: azure
15
+ Requires-Dist: davidkhala-ml-ocr; extra == 'azure'
13
16
  Requires-Dist: davidkhala-utils; extra == 'azure'
14
17
  Requires-Dist: openai; extra == 'azure'
15
18
  Provides-Extra: dify
@@ -19,21 +22,24 @@ Requires-Dist: dify-plugin; extra == 'dify'
19
22
  Provides-Extra: google
20
23
  Requires-Dist: google-adk; extra == 'google'
21
24
  Requires-Dist: google-genai; extra == 'google'
22
- Provides-Extra: hf
23
- Requires-Dist: hf-xet; extra == 'hf'
24
- Requires-Dist: huggingface-hub; extra == 'hf'
25
- Requires-Dist: onnx; extra == 'hf'
26
- Requires-Dist: onnxruntime; extra == 'hf'
27
25
  Provides-Extra: langchain
28
26
  Requires-Dist: langchain; extra == 'langchain'
29
27
  Requires-Dist: langchain-openai; (python_version < '3.14') and extra == 'langchain'
30
28
  Requires-Dist: langgraph; extra == 'langchain'
29
+ Provides-Extra: minimax
30
+ Requires-Dist: anthropic; extra == 'minimax'
31
+ Requires-Dist: openai; extra == 'minimax'
32
+ Provides-Extra: mistral
33
+ Requires-Dist: davidkhala-ml-ocr; extra == 'mistral'
34
+ Requires-Dist: mistralai; extra == 'mistral'
31
35
  Provides-Extra: openrouter
32
36
  Requires-Dist: openrouter; extra == 'openrouter'
33
37
  Provides-Extra: ragflow
34
38
  Requires-Dist: ragflow-sdk; extra == 'ragflow'
35
39
  Provides-Extra: telemetry
36
40
  Requires-Dist: opik; (python_version < '3.14') and extra == 'telemetry'
41
+ Provides-Extra: you
42
+ Requires-Dist: youdotcom; extra == 'you'
37
43
  Description-Content-Type: text/markdown
38
44
 
39
45
  # davidkhala.ai
@@ -0,0 +1,65 @@
1
+ davidkhala/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ davidkhala/ai/opik.py,sha256=YU1XuweMUAzUkhpjxhltt-SBBDBkR3z-PCNo0DqzBRs,39
3
+ davidkhala/ai/you.py,sha256=fmMfJQZcG0e6sKfVQy2jOKZ-jkO-3H6GOGP2U19l4zQ,1759
4
+ davidkhala/ai/agent/README.md,sha256=kIPsx3gOjrpOw7w2qhNEALuCEQkuh4nYp6uBnijdvHE,178
5
+ davidkhala/ai/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ davidkhala/ai/agent/langgraph.py,sha256=vaiHpnYmkjfXiGq-VH0sUn-NXBacnbFW-6E6sUgdNLU,1050
7
+ davidkhala/ai/agent/ragflow.py,sha256=UaK31us6V0NhAPCthGo07rQsm72vlR-McmihC_NDe1g,273
8
+ davidkhala/ai/agent/dify/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ davidkhala/ai/agent/dify/const.py,sha256=gU4lPBe4U2taakN2jhdPMRWXkqlyCg-YRE8JJmtsblo,218
10
+ davidkhala/ai/agent/dify/interface.py,sha256=bTOI38ZjtkgoSw-ysgFwBZ1QkKVAa92gjOnERDoagQA,118
11
+ davidkhala/ai/agent/dify/api/__init__.py,sha256=OevdexhW4rh40uGpzSxmeeff4pslKvygKpxjUQzMc-Y,861
12
+ davidkhala/ai/agent/dify/api/app.py,sha256=XMLwNSpL5BhNZHKx4BEuk9NplIHCToMKXFssrn_7Hu4,3931
13
+ davidkhala/ai/agent/dify/api/knowledge/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ davidkhala/ai/agent/dify/api/knowledge/chunk.py,sha256=AurKJCZQQ2RkitLxMRcRPRKOE2WsTm7JSb6AnjJEgEw,470
15
+ davidkhala/ai/agent/dify/api/knowledge/dataset.py,sha256=JO0Au4TTZIzSagkDI1lOULB5SM-WWGnIiQ7HmcZardM,2981
16
+ davidkhala/ai/agent/dify/api/knowledge/document.py,sha256=sjgzwLWar2CsqO8gF93qeRfzw3fNCLgC4PGxD7QhAhE,1261
17
+ davidkhala/ai/agent/dify/api/knowledge/model.py,sha256=fRv4qMsgPMbNU3Q9c03rU4JedoktQ38IjUDrAjQy-8w,3775
18
+ davidkhala/ai/agent/dify/console/__init__.py,sha256=WKXcjjtnWyljhlgrReSneeD87K6GmgGoCmwKCPdGPdc,380
19
+ davidkhala/ai/agent/dify/console/plugin.py,sha256=qwojlnYaIIRqjV8unN1mkMdOT5scG7ZhuVW8Rz8GgVM,2870
20
+ davidkhala/ai/agent/dify/console/session.py,sha256=agS6i7qe-ZGMOawNTh23_bY2ovm0JtGMDLwEuBuRzyk,1604
21
+ davidkhala/ai/agent/dify/console/knowledge/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ davidkhala/ai/agent/dify/console/knowledge/dataset.py,sha256=QgHPJSPQmiosc7WI6zLPBXaWLIEOHHOEZlVWNlPljuc,2474
23
+ davidkhala/ai/agent/dify/console/knowledge/pipeline.py,sha256=yg4pYx3PHKFl88_deexv6GgACyUcmnJXgvB91wXyfO4,4353
24
+ davidkhala/ai/agent/dify/db/__init__.py,sha256=HYfJEnoFAoJJck2xvTDYx8zpw9Qao7sHXOGvW0diPqw,517
25
+ davidkhala/ai/agent/dify/db/app.py,sha256=IRiSiR0v387p4p3J7M9xEkJ7pfQyO5DL6chpx7Z2IzA,1319
26
+ davidkhala/ai/agent/dify/db/knowledge.py,sha256=GVaK5QmU_VxB8fDxV60uiYiIeR3JEn3IXJTlJHLiT5U,2917
27
+ davidkhala/ai/agent/dify/db/orm.py,sha256=AJ2tVS18g-uyIPJGdEVIPAtoPYUm3KqzSl7av0S8uzA,2188
28
+ davidkhala/ai/agent/dify/db/sys.py,sha256=U_qqopUMlgsilhHaG_ids6gtd-pNiR_Jm0kAr9hIL7M,188
29
+ davidkhala/ai/agent/dify/model/__init__.py,sha256=VXKaNpQFK8J-j9zp5caOgiQxaQCIoUJjWn6NAjTTok0,104
30
+ davidkhala/ai/agent/dify/model/knowledge.py,sha256=e4CbI3tjIn0gsh4t4ZOMp-JQtWFB7yzWvkioSztWJx0,397
31
+ davidkhala/ai/agent/dify/model/workflow.py,sha256=I7_INuD5QAFT_xERmOwAMOKZEccGZ5COnvivv5fNisA,3044
32
+ davidkhala/ai/agent/dify/plugins/__init__.py,sha256=iTWvutlkN9bXgptesi05M447nTeF5hKFAIfn4EviFj0,183
33
+ davidkhala/ai/agent/dify/plugins/file.py,sha256=o-HjHSFwRTNIYs8IxqZUSnBbh-xr8f-xMUM3iU9wCCQ,390
34
+ davidkhala/ai/agent/dify/plugins/firecrawl.py,sha256=lB_f8W_bdg-7PeBKmF0-HdwYyakV_0D3nET5iT-Z1KM,460
35
+ davidkhala/ai/agent/dify/plugins/jina.py,sha256=dQ5iJxDLWtChXb1IjCtsHctgUtgjOiDfWOuR2u0aUIM,190
36
+ davidkhala/ai/agent/dify/plugins/popular.py,sha256=XMuxqRcIko4gCQORg5HCcwCrbgLcaoRZxCYBIgtkrOo,812
37
+ davidkhala/ai/ali/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ davidkhala/ai/ali/agentbay.py,sha256=O5t71GGwtDgBE1zUXJDYe5djMVwSaNOwn5k8zg1xa18,1200
39
+ davidkhala/ai/ali/dashscope.py,sha256=4KWxl8s6PrKtjgszYM6OIv6r5736EXC1HwLcfJo-x-8,2091
40
+ davidkhala/ai/anthropic/__init__.py,sha256=zzELo9KUD9wKKzrEPYmt-wBHPIvInHzgU2ClfbdgzYo,112
41
+ davidkhala/ai/api/__init__.py,sha256=FTsOpTnG5FxM80mFUYir2THfKmVQEGYnsoO_Egdypzo,1137
42
+ davidkhala/ai/api/openrouter.py,sha256=BBM0HsBwo29PChI4ca8tNiEbzE16-WWc95TqW6k-xn8,2527
43
+ davidkhala/ai/api/siliconflow.py,sha256=hxaEIQc2xi394SS8VdCXu2TWPxjpgc3hATzB03LsZQ0,2073
44
+ davidkhala/ai/atlas/__init__.py,sha256=hNjmpp9fk-GGXVZOjrvs_x4j0b_Wlew-BlC5RMTUEMA,746
45
+ davidkhala/ai/google/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ davidkhala/ai/google/adk.py,sha256=QwxYoOzT2Hol03V4NM0PF_HAzUGb4fB18VUAYacYbAY,657
47
+ davidkhala/ai/google/gemini.py,sha256=Xf4HDOOcK4-jEBERzuLnQNFsU61P2fFx4K0z-ijvNHE,214
48
+ davidkhala/ai/mistral/__init__.py,sha256=RpBOQFg67KFSuzaZ1LvuMtIpkfm-iTm6ZepkmHyggrg,371
49
+ davidkhala/ai/mistral/agent.py,sha256=hXHQj6MtxmR86Db4YbtMcdMi5NebX_Tg2bxYo_lL0sY,1652
50
+ davidkhala/ai/mistral/ai.py,sha256=SIIVjmR6oY4BjDTnYCiztkSJgfRF7_a3g21KoDQ0fVo,1324
51
+ davidkhala/ai/mistral/file.py,sha256=Y8RnaONasZX6zJDWzrG0Ez7epQ_BS3CKiIK8EqqX9YE,1402
52
+ davidkhala/ai/mistral/ocr.py,sha256=iImHiv784ZYdqKPwbUJhy7EL9WAXSpc4h4ixTZi3FHY,1736
53
+ davidkhala/ai/model/__init__.py,sha256=ODvM3qaEIjNJcJeU6Nkozj77LUWlC1HcPM-ifYVjA5s,490
54
+ davidkhala/ai/model/chat.py,sha256=1RgvdqMh7wK3bxiu5g3lDI89zVeuASSMKgeCJxqsiTI,2178
55
+ davidkhala/ai/model/embed.py,sha256=2W5Z-qKJUaROxuqV4yqqy7w666PDoh6RBj9gWFKWhUY,217
56
+ davidkhala/ai/model/garden.py,sha256=vcG6-fO0SJckNiPJ1wLJzsu6yKOIdQcVDARI9f9WQNg,178
57
+ davidkhala/ai/openai/__init__.py,sha256=-9SayyencR2nvGycYt_HF-8VqUXmQW9lIwYJV95RXCc,1443
58
+ davidkhala/ai/openai/azure.py,sha256=npF0GA-1jkKL6bsDyMrStkJODn1ShTsqdOKzsLu-mgc,3257
59
+ davidkhala/ai/openai/databricks.py,sha256=Z_ES3KlZuwMjMiGnlAxxrirLInQRVXj2KZs32MHXBbI,736
60
+ davidkhala/ai/openai/native.py,sha256=WhtpBCx_iGyy6tolGjJm1_gJtGo-dcmc_7QvnaxQ6WY,691
61
+ davidkhala/ai/openai/opik.py,sha256=ovodFNDoDO_ygX8_EmeqbZcu8PRTntzsNNQg4JoZKWo,257
62
+ davidkhala/ai/openrouter/__init__.py,sha256=8TLj1noeAvEzhowvkbLu2KUiR8KNijv8OMYRt6G7ApQ,1473
63
+ davidkhala_ai-0.2.2.dist-info/METADATA,sha256=pa6tpzTxuokcqYOsmvCx_oLdhS_JZ_QInQGC0PN7RY0,1837
64
+ davidkhala_ai-0.2.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
65
+ davidkhala_ai-0.2.2.dist-info/RECORD,,