ailoy-py 0.0.1__cp311-cp311-win_amd64.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.
ailoy/runtime.py ADDED
@@ -0,0 +1,273 @@
1
+ from asyncio import Event, to_thread
2
+ from collections import defaultdict
3
+ from typing import Any, AsyncGenerator, Generator, Literal, Optional, TypedDict
4
+
5
+ from .ailoy_py import BrokerClient, generate_uuid, start_threads, stop_threads
6
+
7
+ __all__ = ["Runtime", "AsyncRuntime"]
8
+
9
+
10
+ class Packet(TypedDict):
11
+ packet_type: Literal["respond", "respond_execute"]
12
+ instruction_type: Optional[Literal["call_function", "define_component", "delete_component", "call_method"]]
13
+ headers: list[bool | int | str]
14
+ body: dict[str, Any]
15
+
16
+
17
+ class RuntimeBase:
18
+ def __init__(self, address: str = "inproc://"):
19
+ self.address: str = address
20
+ self._responses: dict[str, Packet] = {}
21
+ self._exec_responses: defaultdict[str, dict[int, Packet]] = defaultdict(dict)
22
+ self._listen_lock: Optional[Event] = None
23
+
24
+ start_threads(self.address)
25
+ self._client: BrokerClient = BrokerClient(address)
26
+ txid = self._send_type1("connect")
27
+ if not txid:
28
+ raise RuntimeError("Connection failed")
29
+ self._sync_listen()
30
+ if not self._responses[txid]["body"]["status"]:
31
+ raise RuntimeError("Connection failed")
32
+ del self._responses[txid]
33
+
34
+ def __del__(self):
35
+ self.stop()
36
+
37
+ def __enter__(self):
38
+ return self
39
+
40
+ def __exit__(self, type, value, traceback):
41
+ self.stop()
42
+
43
+ def stop(self):
44
+ if self._client:
45
+ txid = self._send_type1("disconnect")
46
+ if not txid:
47
+ raise RuntimeError("Disconnection failed")
48
+ while txid not in self._responses:
49
+ self._sync_listen()
50
+ if not self._responses[txid]["body"]["status"]:
51
+ raise RuntimeError("Disconnection failed")
52
+ self._client = None
53
+ stop_threads(self.address)
54
+
55
+ def _send_type1(self, ptype: Literal["connect", "disconnect"]) -> Optional[str]:
56
+ txid = generate_uuid()
57
+ if self._client.send_type1(txid, ptype):
58
+ return txid
59
+ raise RuntimeError("Failed to send packet")
60
+
61
+ def _send_type2(
62
+ self,
63
+ ptype: Literal["subscribe", "unsubscribe", "execute"],
64
+ itype: Literal["call_function", "define_component", "delete_component", "call_method"],
65
+ *args,
66
+ ):
67
+ txid = generate_uuid()
68
+ if self._client.send_type2(txid, ptype, itype, *args):
69
+ return txid
70
+ raise RuntimeError("Failed to send packet")
71
+
72
+ def _send_type3(
73
+ self,
74
+ ptype: Literal["respond", "respond_execute"],
75
+ status: bool,
76
+ *args,
77
+ ):
78
+ txid = generate_uuid()
79
+ if self._client.send_type2(txid, ptype, status, *args):
80
+ return txid
81
+ raise RuntimeError("Failed to send packet")
82
+
83
+ def _sync_listen(self) -> None:
84
+ packet = self._client.listen()
85
+ if packet is not None:
86
+ txid = packet["headers"][0]
87
+ if packet["packet_type"] == "respond_execute":
88
+ idx = packet["headers"][1]
89
+ self._exec_responses[txid][idx] = packet
90
+ else:
91
+ self._responses[txid] = packet
92
+
93
+ async def _listen(self) -> None:
94
+ # If listen lock exists -> wait
95
+ if self._listen_lock:
96
+ await self._listen_lock.wait()
97
+ else:
98
+ # Create a new event
99
+ self._listen_lock = Event()
100
+ # Listen packet
101
+ packet = await to_thread(self._client.listen)
102
+ if packet is not None:
103
+ txid = packet["headers"][0]
104
+ if packet["packet_type"] == "respond_execute":
105
+ idx = packet["headers"][1]
106
+ self._exec_responses[txid][idx] = packet
107
+ else:
108
+ self._responses[txid] = packet
109
+ # Emit event
110
+ self._listen_lock.set()
111
+ self._listen_lock = None
112
+
113
+
114
+ class Runtime(RuntimeBase):
115
+ def __init__(self, address: str = "inproc://"):
116
+ super().__init__(address)
117
+
118
+ def call(self, func_name: str, input: Any) -> Any:
119
+ rv = [v for v in self.call_iter(func_name, input)]
120
+ if len(rv) == 0:
121
+ return None
122
+ elif len(rv) == 1:
123
+ return rv[0]
124
+ else:
125
+ return rv
126
+
127
+ def call_iter(self, func_name: str, input: Any) -> Generator[Any, None, None]:
128
+ txid = self._send_type2("execute", "call_function", func_name, input)
129
+
130
+ def generator():
131
+ idx = 0
132
+ finished = False
133
+ while not finished:
134
+ while idx not in self._exec_responses[txid]:
135
+ self._sync_listen()
136
+ packet = self._exec_responses[txid].pop(idx)
137
+ if not packet["body"]["status"]:
138
+ raise RuntimeError(packet["body"]["reason"])
139
+ if packet["headers"][2]:
140
+ finished = True
141
+ yield packet["body"]["out"]
142
+ idx += 1
143
+ del self._exec_responses[txid]
144
+
145
+ return generator()
146
+
147
+ def define(self, comp_type: str, comp_name: str, input: Any) -> None:
148
+ txid = self._send_type2("execute", "define_component", comp_type, comp_name, input)
149
+ while 0 not in self._exec_responses[txid]:
150
+ self._sync_listen()
151
+ packet = self._exec_responses[txid][0]
152
+ if not packet["body"]["status"]:
153
+ raise RuntimeError(packet["body"]["reason"])
154
+ del self._exec_responses[txid]
155
+
156
+ def delete(self, comp_name: str) -> None:
157
+ txid = self._send_type2("execute", "delete_component", comp_name)
158
+ while 0 not in self._exec_responses[txid]:
159
+ self._sync_listen()
160
+ packet = self._exec_responses[txid][0]
161
+ if not packet["body"]["status"]:
162
+ raise RuntimeError(packet["body"]["reason"])
163
+ del self._exec_responses[txid]
164
+
165
+ def call_method(self, comp_name: str, func_name: str, input: Any) -> Any:
166
+ rv = [v for v in self.call_iter_method(comp_name, func_name, input)]
167
+ if len(rv) == 0:
168
+ return None
169
+ elif len(rv) == 1:
170
+ return rv[0]
171
+ else:
172
+ return rv
173
+
174
+ def call_iter_method(self, comp_name: str, func_name: str, input: Any) -> Generator[Any, None, None]:
175
+ txid = self._send_type2("execute", "call_method", comp_name, func_name, input)
176
+
177
+ def generator():
178
+ idx = 0
179
+ finished = False
180
+ while not finished:
181
+ while idx not in self._exec_responses[txid]:
182
+ self._sync_listen()
183
+ packet = self._exec_responses[txid].pop(idx)
184
+ if not packet["body"]["status"]:
185
+ raise RuntimeError(packet["body"]["reason"])
186
+ if packet["headers"][2]:
187
+ finished = True
188
+ yield packet["body"]["out"]
189
+ idx += 1
190
+ del self._exec_responses[txid]
191
+
192
+ return generator()
193
+
194
+
195
+ class AsyncRuntime(RuntimeBase):
196
+ def __init__(self, address: str = "inproc://"):
197
+ super().__init__(address)
198
+
199
+ async def call(self, func_name: str, input: Any) -> Any:
200
+ rv = [v async for v in self.call_iter(func_name, input)]
201
+ if len(rv) == 0:
202
+ return None
203
+ elif len(rv) == 1:
204
+ return rv[0]
205
+ else:
206
+ return rv
207
+
208
+ def call_iter(self, func_name: str, input: Any) -> AsyncGenerator[Any, None]:
209
+ txid = self._send_type2("execute", "call_function", func_name, input)
210
+
211
+ async def generator():
212
+ idx = 0
213
+ finished = False
214
+ while not finished:
215
+ while idx not in self._exec_responses[txid]:
216
+ await self._listen()
217
+ packet = self._exec_responses[txid].pop(idx)
218
+ if not packet["body"]["status"]:
219
+ raise RuntimeError(packet["body"]["reason"])
220
+ if packet["headers"][2]:
221
+ finished = True
222
+ yield packet["body"]["out"]
223
+ idx += 1
224
+ del self._exec_responses[txid]
225
+
226
+ return generator()
227
+
228
+ async def define(self, comp_type: str, comp_name: str, input: Any) -> None:
229
+ txid = self._send_type2("execute", "define_component", comp_type, comp_name, input)
230
+ while 0 not in self._exec_responses[txid]:
231
+ await self._listen()
232
+ packet = self._exec_responses[txid][0]
233
+ if not packet["body"]["status"]:
234
+ raise RuntimeError(packet["body"]["reason"])
235
+ del self._exec_responses[txid]
236
+
237
+ async def delete(self, comp_name: str) -> None:
238
+ txid = self._send_type2("execute", "delete_component", comp_name)
239
+ while 0 not in self._exec_responses[txid]:
240
+ await self._listen()
241
+ packet = self._exec_responses[txid][0]
242
+ if not packet["body"]["status"]:
243
+ raise RuntimeError(packet["body"]["reason"])
244
+ del self._exec_responses[txid]
245
+
246
+ async def call_method(self, comp_name: str, func_name: str, input: Any) -> Any:
247
+ rv = [v async for v in self.call_iter_method(comp_name, func_name, input)]
248
+ if len(rv) == 0:
249
+ return None
250
+ elif len(rv) == 1:
251
+ return rv[0]
252
+ else:
253
+ return rv
254
+
255
+ def call_iter_method(self, comp_name: str, func_name: str, input: Any) -> AsyncGenerator[Any, None]:
256
+ txid = self._send_type2("execute", "call_method", comp_name, func_name, input)
257
+
258
+ async def generator():
259
+ idx = 0
260
+ finished = False
261
+ while not finished:
262
+ while idx not in self._exec_responses[txid]:
263
+ await self._listen()
264
+ packet = self._exec_responses[txid].pop(idx)
265
+ if not packet["body"]["status"]:
266
+ raise RuntimeError(packet["body"]["reason"])
267
+ if packet["headers"][2]:
268
+ finished = True
269
+ yield packet["body"]["out"]
270
+ idx += 1
271
+ del self._exec_responses[txid]
272
+
273
+ return generator()
ailoy/vector_store.py ADDED
@@ -0,0 +1,207 @@
1
+ from typing import Any, Dict, List, Literal, Optional
2
+
3
+ from pydantic import BaseModel, TypeAdapter
4
+
5
+ from ailoy.runtime import Runtime, generate_uuid
6
+
7
+ __all__ = ["VectorStore"]
8
+
9
+
10
+ class VectorStoreInsertItem(BaseModel):
11
+ document: str
12
+ metadata: Optional[Dict[str, Any]] = None
13
+
14
+
15
+ class VectorStoreRetrieveItem(VectorStoreInsertItem):
16
+ id: str
17
+ similarity: float
18
+
19
+
20
+ class ComponentState(BaseModel):
21
+ embedding_model_name: str
22
+ vector_store_name: str
23
+ valid: bool
24
+
25
+
26
+ class VectorStore:
27
+ """
28
+ The `VectorStore` class provides a high-level abstraction for storing and retrieving documents.
29
+ It mainly consists of two modules - embedding model and vector store.
30
+
31
+ It supports embedding text using AI and interfacing with pluggable vector store backends such as FAISS or ChromaDB.
32
+ This class handles initialization, insertion, similarity-based retrieval, and cleanup.
33
+
34
+ Typical usage involves:
35
+ 1. Initializing the store via `initialize()`
36
+ 2. Inserting documents via `insert()`
37
+ 3. Querying similar documents via `retrieve()`
38
+
39
+ The embedding model and vector store are defined dynamically within the provided runtime.
40
+ """
41
+
42
+ def __init__(
43
+ self,
44
+ runtime: Runtime,
45
+ embedding_model_name: Literal["BAAI/bge-m3"],
46
+ vector_store_name: Literal["faiss", "chromadb"],
47
+ url: Optional[str] = None,
48
+ collection: Optional[str] = None,
49
+ embedding_model_attrs: dict[str, Any] = dict(),
50
+ vector_store_attrs: dict[str, Any] = dict(),
51
+ ):
52
+ """
53
+ Creates an instance.
54
+
55
+ :param runtime: The runtime environment used to manage components.
56
+ :param embedding_model_name: The name of the embedding model to use. Currently it only supports `BAAI/bge-m3`.
57
+ :param url: (ChromaDB only) URL of the database.
58
+ :param collection: (ChromaDB only) The collection name of the database.
59
+ :param vector_store_name: The name of the vector store provider (One of faiss or chromaDB).
60
+ :param embedding_model_attrs: Additional initialization parameters (for `define_component` runtime call).
61
+ :param vector_store_attrs: Additional initialization parameters (for `define_component` runtime call).
62
+ """
63
+ self._runtime = runtime
64
+ self._component_state = ComponentState(
65
+ embedding_model_name=generate_uuid(),
66
+ vector_store_name=generate_uuid(),
67
+ valid=False,
68
+ )
69
+ self.define(
70
+ embedding_model_name,
71
+ vector_store_name,
72
+ url,
73
+ collection,
74
+ embedding_model_attrs,
75
+ vector_store_attrs,
76
+ )
77
+
78
+ def __del__(self):
79
+ self.delete()
80
+
81
+ def __enter__(self):
82
+ return self
83
+
84
+ def __exit__(self, type, value, traceback):
85
+ self.delete()
86
+
87
+ def define(
88
+ self,
89
+ embedding_model_name: Literal["BAAI/bge-m3"],
90
+ vector_store_name: Literal["faiss", "chromadb"],
91
+ url: Optional[str] = None,
92
+ collection: Optional[str] = None,
93
+ embedding_model_attrs: dict[str, Any] = dict(),
94
+ vector_store_attrs: dict[str, Any] = dict(),
95
+ ):
96
+ """
97
+ Defines the embedding model and vector store components to the runtime.
98
+ This must be called before using any other method in the class. If already defined, this is a no-op.
99
+ """
100
+ if self._component_state.valid:
101
+ return
102
+
103
+ # Dimension size may be different based on embedding model
104
+ dimension = 1024
105
+
106
+ # Initialize embedding model
107
+ if embedding_model_name == "BAAI/bge-m3":
108
+ dimension = 1024
109
+ self._runtime.define(
110
+ "tvm_embedding_model",
111
+ self._component_state.embedding_model_name,
112
+ {
113
+ "model": "BAAI/bge-m3",
114
+ **embedding_model_attrs,
115
+ },
116
+ )
117
+ else:
118
+ raise NotImplementedError(f"Unsupprted embedding model: {embedding_model_name}")
119
+
120
+ # Initialize vector store
121
+ if vector_store_name == "faiss":
122
+ if "dimension" not in vector_store_attrs:
123
+ vector_store_attrs["dimension"] = dimension
124
+ self._runtime.define("faiss_vector_store", self._component_state.vector_store_name, vector_store_attrs)
125
+ elif vector_store_name == "chromadb":
126
+ if "url" not in vector_store_attrs:
127
+ vector_store_attrs["url"] = url
128
+ if "collection" not in vector_store_attrs:
129
+ vector_store_attrs["collection"] = collection
130
+ self._runtime.define("chromadb_vector_store", self._component_state.vector_store_name, vector_store_attrs)
131
+ else:
132
+ raise NotImplementedError(f"Unsupprted vector store: {vector_store_name}")
133
+
134
+ self._component_state.valid = True
135
+
136
+ def delete(self):
137
+ """
138
+ Delete resources from the runtime.
139
+ This should be called when the VectorStore is no longer needed. If already deleted, this is a no-op.
140
+ """
141
+ if not self._component_state.valid:
142
+ return
143
+
144
+ self._runtime.delete(self._component_state.embedding_model_name)
145
+ self._runtime.delete(self._component_state.vector_store_name)
146
+ self._component_state.valid = False
147
+
148
+ # TODO: add NDArray typing
149
+ def embedding(self, text: str) -> Any:
150
+ """
151
+ Generates an embedding vector for the given input text using the embedding model.
152
+
153
+ :param text: Input text to embed.
154
+ :returns: The resulting embedding vector.
155
+ """
156
+ resp = self._runtime.call_method(
157
+ self._component_state.embedding_model_name,
158
+ "infer",
159
+ {
160
+ "prompt": text,
161
+ },
162
+ )
163
+ return resp["embedding"]
164
+
165
+ def insert(self, document: str, metadata: Optional[Dict[str, Any]] = None):
166
+ """
167
+ Inserts a new document into the vector store.
168
+
169
+ :param document: The raw text document to insert.
170
+ :param metadata: Metadata records additional information about the document.
171
+ """
172
+ embedding = self.embedding(document)
173
+ self._runtime.call_method(
174
+ self._component_state.vector_store_name,
175
+ "insert",
176
+ {
177
+ "embedding": embedding,
178
+ "document": document,
179
+ "metadata": metadata,
180
+ },
181
+ )
182
+
183
+ def retrieve(self, query: str, top_k: int = 5) -> List[VectorStoreRetrieveItem]:
184
+ """
185
+ Retrieves the top-K most similar documents to the given query.
186
+
187
+ :param query: The input query string to search for similar content.
188
+ :param top_k: Number of top similar documents to retrieve.
189
+ :returns: A list of retrieved items.
190
+ """
191
+ embedding = self.embedding(query)
192
+ resp = self._runtime.call_method(
193
+ self._component_state.vector_store_name,
194
+ "retrieve",
195
+ {
196
+ "query_embedding": embedding,
197
+ "top_k": top_k,
198
+ },
199
+ )
200
+ results = TypeAdapter(List[VectorStoreRetrieveItem]).validate_python(resp["results"])
201
+ return results
202
+
203
+ def clean(self):
204
+ """
205
+ Removes all entries from the vector store.
206
+ """
207
+ self._runtime.call_method(self._component_state.vector_store_name, "clean", {})
@@ -0,0 +1,2 @@
1
+ Version: 1.10.1
2
+ Arguments: ['C:\\hostedtoolcache\\windows\\Python\\3.11.9\\x64\\Scripts\\delvewheel', 'repair', '-w', 'wheelhouse', 'D:\\a\\ailoy\\ailoy\\bindings\\python\\dist\\ailoy_py-0.0.1-cp311-cp311-win_amd64.whl', '--add-path', 'D:\\a\\ailoy\\ailoy\\bindings\\python\\build\\_deps\\mlc-llm-build\\Release;D:\\a\\ailoy\\ailoy\\bindings\\python\\build\\_deps\\mlc-llm-build\\tvm\\Release', '--exclude', 'vulkan-1.dll']
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.4
2
+ Name: ailoy-py
3
+ Version: 0.0.1
4
+ Summary: Python binding for Ailoy runtime APIs
5
+ Author-Email: "Brekkylab Inc." <contact@brekkylab.com>
6
+ License-Expression: Apache-2.0
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
10
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Requires-Python: >=3.10
17
+ Requires-Dist: anyio>=4.9.0
18
+ Requires-Dist: jmespath>=1.0.1
19
+ Requires-Dist: mcp>=1.8.0
20
+ Requires-Dist: numpy>=2.0.2
21
+ Requires-Dist: pydantic>=2.11.4
22
+ Requires-Dist: rich>=14.0.0
23
+ Requires-Dist: typer>=0.15.4
24
+ Description-Content-Type: text/markdown
25
+
26
+ # ailoy-py
27
+
28
+ Python binding for Ailoy runtime APIs.
29
+
30
+ See our [documentation](https://brekkylab.github.io/ailoy) for more details.
31
+
32
+ ## Install
33
+
34
+ ```bash
35
+ pip install ailoy-py
36
+ ```
37
+
38
+ ## Quickstart
39
+
40
+ ```python
41
+ from ailoy import Runtime, Agent
42
+
43
+ # The runtime must be started to use Ailoy
44
+ rt = Runtime()
45
+
46
+ # Defines an agent
47
+ # During this step, the model parameters are downloaded and the LLM is set up for execution
48
+ with Agent(rt, model_name="Qwen/Qwen3-0.6B") as agent:
49
+ # This is where the actual LLM call happens
50
+ for resp in agent.query("Please give me a short poem about AI"):
51
+ agent.print(resp)
52
+
53
+ # Stop the runtime
54
+ rt.stop()
55
+ ```
56
+
57
+ ## Building from source
58
+
59
+ ### Prerequisites
60
+
61
+ - Python 3.10 or higher
62
+ - C/C++ compiler
63
+ (recommended versions are below)
64
+ - GCC >= 13
65
+ - LLVM Clang >= 17
66
+ - Apple Clang >= 15
67
+ - MSVC >= 19.29
68
+ - CMake >= 3.24.0
69
+ - Git
70
+ - OpenSSL
71
+ - Rust & Cargo >= 1.82.0
72
+ - OpenMP
73
+ - BLAS
74
+ - LAPACK
75
+ - Vulkan SDK (if you are using vulkan)
76
+
77
+
78
+ ### Setup development environment
79
+
80
+ ```bash
81
+ pip install -e .
82
+ ```
83
+
84
+ ### Generate wheel
85
+
86
+ ```bash
87
+ python -m build -w
88
+ ```
@@ -0,0 +1,20 @@
1
+ ailoy/agent.py,sha256=u_-91hq9-yhobcRqBizNUfUglyAIfnVNKSKBWgQpw_U,25727
2
+ ailoy/ailoy_py.cp311-win_amd64.pyd,sha256=lMcBt4hMRWTw85fEGAPFp40XZ-sz18u5kaekSfpXBXQ,13466112
3
+ ailoy/ailoy_py.pyi,sha256=wr_-KGTI-O9usNdzTyszn4mAjnjiV2cJf0aBct2PKrU,1020
4
+ ailoy/runtime.py,sha256=D5_j0niftXZOd7dkxCbxs7H9uhVarizXctBooFZWrP8,10270
5
+ ailoy/vector_store.py,sha256=TQiwboJmYl6kvtUHyx6P9JVJrdYbbfpx7lwncJ5tZNI,7572
6
+ ailoy/__init__.py,sha256=FSLZpDs2vu9rwEcgQA2ps07QyiHM2ZDl797Yvu59AYM,481
7
+ ailoy/cli/model.py,sha256=t1-uO5vRDUomxIDpuMduPVCOKBR9VHMXqMcz38m_-YI,3091
8
+ ailoy/cli/__main__.py,sha256=JUWtde3gYqKxuCtihgr5g2MAQgj151wv41OOZv2uHsQ,190
9
+ ailoy/presets/tools/calculator.json,sha256=8G5t1PGyM7ZmX97WNfrF-H-x7LR8s_O15ppY_APFnVo,1064
10
+ ailoy/presets/tools/frankfurter.json,sha256=nM26DjkiPgamhL1Re7Gi_fnhUQyegDxcquEFBD0af5g,1185
11
+ ailoy/presets/tools/nytimes.json,sha256=diio4FSJGHvumX05MQ0RgrqZzggpjyX8ekBPZ4NCmPo,944
12
+ ailoy/presets/tools/tmdb.json,sha256=o9dg9bdfFhvgrhVGw5hP3V0EgGvBzm5ZrTtxrb1PerM,7231
13
+ ailoy_py-0.0.1.dist-info/DELVEWHEEL,sha256=N1WWsN84GhbnbKUWfaT_yUNvOYv-6-WBoT50BrNsxz0,424
14
+ ailoy_py-0.0.1.dist-info/entry_points.txt,sha256=gVG45uDE6kef0wm6SEMYSgZgRNNRhSAeP2n2lPR00dI,50
15
+ ailoy_py-0.0.1.dist-info/METADATA,sha256=FAyzKTteIMgZse5H99IVQ5q2ScjU9hlTuOggBNrgTF0,2010
16
+ ailoy_py-0.0.1.dist-info/RECORD,,
17
+ ailoy_py-0.0.1.dist-info/WHEEL,sha256=XudZ88buj5mYv1il7ey7lY9YY_b5GZq6c5RjX3rDALo,106
18
+ ailoy_py.libs/msvcp140-9867ece6bcf7e4746fa7e6671b0a17bd.dll,sha256=cDrXxV8uCWYH7Gp3qLX1LVNdvnH93wIel8vLvCP3SSo,576128
19
+ ailoy_py.libs/tvm_runtime-d2432b09972b70bd5375e7bd4a3ca45e.dll,sha256=RCpWKm-vYLReTFDQlTsTw7g6j7OuxdgKQfY1vAQg5fk,1997824
20
+ ailoy_py.libs/vcomp140-f99ecd9a7e9d3df487b10cf7a201d515.dll,sha256=42pcXjKbx6811PqmEKKa7ugmp4EOBnEvD1Tpss_mpyg,192112
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: scikit-build-core 0.11.3
3
+ Root-Is-Purelib: false
4
+ Tag: cp311-cp311-win_amd64
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ ailoy = ailoy.cli.__main__:app
3
+