@1kbirds/chidori 0.1.26 → 3.4.0
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.
- package/README.md +138 -6
- package/dist/agent-env.d.ts +38 -0
- package/dist/agent-env.js +1 -0
- package/dist/agent.d.ts +487 -0
- package/dist/agent.js +46 -0
- package/dist/index.d.ts +332 -0
- package/dist/index.js +318 -0
- package/package.json +34 -33
- package/src/agent-env.ts +43 -0
- package/src/agent.ts +548 -0
- package/src/index.ts +580 -0
- package/CHANGELOG.md +0 -33
- package/Cargo.toml +0 -83
- package/build.rs +0 -7
- package/package_node/index.d.ts +0 -0
- package/package_node/index.js +0 -130
- package/pyproject.toml +0 -35
- package/src/lib.rs +0 -23
- package/src/translations/mod.rs +0 -9
- package/src/translations/nodejs.rs +0 -739
- package/src/translations/python.rs +0 -921
- package/src/translations/rust.rs +0 -737
- package/src/translations/shared.rs +0 -49
- package/src/translations/wasm.rs +0 -1
- package/tests/nodejs/chidori.test.js +0 -41
- package/tests/nodejs/nodeHandle.test.js +0 -15
- package/tests/python/test_chidori.py +0 -30
|
@@ -1,921 +0,0 @@
|
|
|
1
|
-
use std::collections::VecDeque;
|
|
2
|
-
use pyo3::exceptions;
|
|
3
|
-
use pyo3::prelude::*;
|
|
4
|
-
use tonic::{Response, Status};
|
|
5
|
-
use futures::executor;
|
|
6
|
-
use futures::StreamExt;
|
|
7
|
-
use pyo3::types::{PyDict, PyList, PyString};
|
|
8
|
-
use pyo3::prelude::*;
|
|
9
|
-
use std::collections::HashMap;
|
|
10
|
-
use std::sync::{Arc};
|
|
11
|
-
use tokio::sync::Mutex;
|
|
12
|
-
use std::time::Duration;
|
|
13
|
-
use tokio::runtime::Runtime;
|
|
14
|
-
use log::{debug, info};
|
|
15
|
-
use pyo3::exceptions::PyTypeError;
|
|
16
|
-
use tonic::transport::Channel;
|
|
17
|
-
use ::prompt_graph_exec::tonic_runtime::run_server;
|
|
18
|
-
use ::prompt_graph_core::proto2::execution_runtime_client::ExecutionRuntimeClient;
|
|
19
|
-
use ::prompt_graph_core::proto2::{File, Empty, ExecutionStatus, RequestInputProposalResponse, RequestOnlyId, RequestFileMerge, RequestAtFrame, RequestNewBranch, RequestListBranches, ListBranchesRes, QueryAtFrame, Query, QueryAtFrameResponse, SerializedValue, ChangeValueWithCounter, NodeWillExecuteOnBranch, FileAddressedChangeValueWithCounter, FilteredPollNodeWillExecuteEventsRequest, RespondPollNodeWillExecuteEvents, RequestAckNodeWillExecuteEvent, ChangeValue, Path, SerializedValueObject, SerializedValueArray, Item};
|
|
20
|
-
use ::prompt_graph_core::proto2::prompt_graph_node_loader::LoadFrom;
|
|
21
|
-
use ::prompt_graph_core::proto2::serialized_value::Val;
|
|
22
|
-
use ::prompt_graph_core::graph_definition::{create_prompt_node, create_op_map, create_code_node, create_component_node, create_vector_memory_node, create_observation_node, create_node_parameter, SourceNodeType, create_loader_node, create_custom_node};
|
|
23
|
-
use ::prompt_graph_core::utils::wasm_error::CoreError;
|
|
24
|
-
use ::prompt_graph_core::build_runtime_graph::graph_parse::{CleanedDefinitionGraph, CleanIndividualNode, construct_query_from_output_type, derive_for_individual_node};
|
|
25
|
-
use crate::register_node_handle;
|
|
26
|
-
use crate::translations::rust::{Chidori, CustomNodeCreateOpts, DenoCodeNodeCreateOpts, GraphBuilder, Handler, NodeHandle, PromptNodeCreateOpts, VectorMemoryNodeCreateOpts};
|
|
27
|
-
|
|
28
|
-
#[derive(Debug)]
|
|
29
|
-
pub struct CoreErrorWrapper(CoreError);
|
|
30
|
-
|
|
31
|
-
impl std::convert::From<CoreErrorWrapper> for PyErr {
|
|
32
|
-
fn from(err: CoreErrorWrapper) -> PyErr {
|
|
33
|
-
exceptions::PyOSError::new_err(err.0.to_string())
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
impl std::convert::From<CoreError> for PyErrWrapper {
|
|
38
|
-
fn from(err: CoreError) -> PyErrWrapper {
|
|
39
|
-
PyErrWrapper(exceptions::PyOSError::new_err(err.to_string()))
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
impl std::convert::From<anyhow::Error> for PyErrWrapper {
|
|
44
|
-
fn from(err: anyhow::Error) -> PyErrWrapper {
|
|
45
|
-
PyErrWrapper(exceptions::PyOSError::new_err(err.to_string()))
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
#[derive(Debug)]
|
|
51
|
-
pub struct PyErrWrapper(pyo3::PyErr);
|
|
52
|
-
|
|
53
|
-
#[derive(Debug)]
|
|
54
|
-
pub struct AnyhowErrWrapper(anyhow::Error);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
impl std::convert::From<tonic::transport::Error> for PyErrWrapper {
|
|
58
|
-
fn from(status: tonic::transport::Error) -> Self {
|
|
59
|
-
// Convert the `Status` to a `PyErr` here, then wrap it in `PyErrWrapper`.
|
|
60
|
-
PyErrWrapper(exceptions::PyOSError::new_err(status.to_string()))
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
impl std::convert::From<Status> for PyErrWrapper {
|
|
65
|
-
fn from(status: Status) -> Self {
|
|
66
|
-
// Convert the `Status` to a `PyErr` here, then wrap it in `PyErrWrapper`.
|
|
67
|
-
PyErrWrapper(exceptions::PyOSError::new_err(status.message().to_string()))
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
impl std::convert::From<PyErrWrapper> for PyErr {
|
|
73
|
-
fn from(err: PyErrWrapper) -> PyErr {
|
|
74
|
-
err.0
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
impl std::convert::From<AnyhowErrWrapper> for PyErr {
|
|
79
|
-
fn from(err: AnyhowErrWrapper) -> PyErr {
|
|
80
|
-
exceptions::PyOSError::new_err(err.0.to_string())
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
impl Into<pyo3::PyResult<()>> for PyErrWrapper {
|
|
85
|
-
fn into(self) -> pyo3::PyResult<()> {
|
|
86
|
-
Err(self.0)
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
pub struct PyExecutionStatus(ExecutionStatus);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
impl IntoPy<Py<PyAny>> for PyExecutionStatus {
|
|
95
|
-
fn into_py(self, py: Python) -> Py<PyAny> {
|
|
96
|
-
let exec_status = self.0;
|
|
97
|
-
let dict = PyDict::new(py);
|
|
98
|
-
dict.set_item("id", exec_status.id).unwrap();
|
|
99
|
-
dict.set_item("monotonic_counter", exec_status.monotonic_counter).unwrap();
|
|
100
|
-
dict.set_item("branch", exec_status.branch).unwrap();
|
|
101
|
-
dict.into_py(py)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
pub struct PyResponseExecutionStatus(Response<ExecutionStatus>);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
impl IntoPy<Py<PyAny>> for PyResponseExecutionStatus {
|
|
109
|
-
fn into_py(self, py: Python) -> Py<PyAny> {
|
|
110
|
-
let PyResponseExecutionStatus(resp) = self;
|
|
111
|
-
let exec_status = resp.into_inner();
|
|
112
|
-
let dict = PyDict::new(py);
|
|
113
|
-
dict.set_item("id", exec_status.id).unwrap();
|
|
114
|
-
dict.set_item("monotonic_counter", exec_status.monotonic_counter).unwrap();
|
|
115
|
-
dict.set_item("branch", exec_status.branch).unwrap();
|
|
116
|
-
dict.into_py(py)
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
pub struct PyListBranchesRes(Response<ListBranchesRes>);
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
impl IntoPy<Py<PyAny>> for PyListBranchesRes {
|
|
125
|
-
fn into_py(self, py: Python) -> Py<PyAny> {
|
|
126
|
-
let PyListBranchesRes(resp) = self;
|
|
127
|
-
let branches = resp.into_inner();
|
|
128
|
-
let branch_list = branches.branches.into_iter().map(|branch| {
|
|
129
|
-
let mut dict = PyDict::new(py);
|
|
130
|
-
dict.set_item("id", branch.id).unwrap();
|
|
131
|
-
dict.set_item("diverges_at_counter", branch.diverges_at_counter).unwrap();
|
|
132
|
-
dict.set_item("source_branch_ids", format!("{:?}", branch.source_branch_ids)).unwrap();
|
|
133
|
-
dict
|
|
134
|
-
}).collect::<Vec<_>>();
|
|
135
|
-
PyList::new(py, branch_list).into_py(py)
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
pub struct PyQueryAtFrameResponse(Response<QueryAtFrameResponse>);
|
|
141
|
-
|
|
142
|
-
impl IntoPy<Py<PyAny>> for PyQueryAtFrameResponse {
|
|
143
|
-
fn into_py(self, py: Python) -> Py<PyAny> {
|
|
144
|
-
let PyQueryAtFrameResponse(resp) = self;
|
|
145
|
-
let res = resp.into_inner();
|
|
146
|
-
|
|
147
|
-
let mut dict = PyDict::new(py);
|
|
148
|
-
res.values.into_iter().for_each(|value| {
|
|
149
|
-
let c = value.change_value.unwrap();
|
|
150
|
-
let k = c.path.unwrap().address.join(":");
|
|
151
|
-
let v = c.value.unwrap();
|
|
152
|
-
// TODO: SerializeValue to python
|
|
153
|
-
dict.set_item(k, SerializedValueWrapper(v)).unwrap();
|
|
154
|
-
});
|
|
155
|
-
PyList::new(py, dict).into_py(py)
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
#[derive(Debug)]
|
|
160
|
-
pub struct SerializedValueWrapper(SerializedValue);
|
|
161
|
-
|
|
162
|
-
impl ToPyObject for SerializedValueWrapper {
|
|
163
|
-
fn to_object(&self, py: Python<'_>) -> PyObject {
|
|
164
|
-
if let None = self.0.val {
|
|
165
|
-
let x: Option<bool> = None;
|
|
166
|
-
return x.into_py(py);
|
|
167
|
-
}
|
|
168
|
-
match self.0.val.as_ref().unwrap() {
|
|
169
|
-
Val::Float(x) => { x.into_py(py) }
|
|
170
|
-
Val::Number(x) => { x.into_py(py) }
|
|
171
|
-
Val::String(x) => { x.into_py(py) }
|
|
172
|
-
Val::Boolean(x) => { x.into_py(py) }
|
|
173
|
-
Val::Array(val) => {
|
|
174
|
-
let py_list = PyList::empty(py);
|
|
175
|
-
for item in &val.values {
|
|
176
|
-
py_list.append(SerializedValueWrapper(item.clone()).to_object(py)).unwrap();
|
|
177
|
-
}
|
|
178
|
-
py_list.into_py(py)
|
|
179
|
-
}
|
|
180
|
-
Val::Object(val) => {
|
|
181
|
-
let py_dict = PyDict::new(py);
|
|
182
|
-
for (key, value) in &val.values {
|
|
183
|
-
py_dict.set_item(key, SerializedValueWrapper(value.clone()).to_object(py)).unwrap();
|
|
184
|
-
}
|
|
185
|
-
py_dict.into_py(py)
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
#[derive(Debug)]
|
|
192
|
-
pub struct ChangeValueWithCounterWrapper(ChangeValueWithCounter);
|
|
193
|
-
|
|
194
|
-
impl IntoPy<Py<PyAny>> for ChangeValueWithCounterWrapper {
|
|
195
|
-
fn into_py(self, py: Python) -> Py<PyAny> {
|
|
196
|
-
let mut dict = PyDict::new(py);
|
|
197
|
-
self.0.filled_values.into_iter().for_each(|c| {
|
|
198
|
-
let k = c.path.map(|path| path.address.join(":"));
|
|
199
|
-
let v = c.value;
|
|
200
|
-
if let (Some(k), Some(v)) = (k, v) {
|
|
201
|
-
dict.set_item(k, SerializedValueWrapper(v)).unwrap();
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
PyList::new(py, dict).into_py(py)
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
fn add_to_dict<'p>(
|
|
209
|
-
py: Python<'p>,
|
|
210
|
-
keys: &Vec<String>,
|
|
211
|
-
value: PyObject,
|
|
212
|
-
d: &'p PyDict,
|
|
213
|
-
) -> PyResult<()> {
|
|
214
|
-
if keys.len() == 1 {
|
|
215
|
-
d.set_item(keys[0].clone(), value)?;
|
|
216
|
-
} else {
|
|
217
|
-
let key = &keys[0];
|
|
218
|
-
if d.contains(key)? {
|
|
219
|
-
let nested_dict = d.get_item(key).unwrap().downcast::<PyDict>()?;
|
|
220
|
-
add_to_dict(py, &keys[1..].to_vec(), value, &nested_dict)?;
|
|
221
|
-
} else {
|
|
222
|
-
let nested_dict = PyDict::new(py);
|
|
223
|
-
d.set_item(key, &nested_dict)?;
|
|
224
|
-
add_to_dict(py, &keys[1..].to_vec(), value, &nested_dict)?;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
Ok(())
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
fn pyany_to_serialized_value(p: &PyAny) -> SerializedValue {
|
|
232
|
-
match p.get_type().name() {
|
|
233
|
-
Ok(s) => {
|
|
234
|
-
match s {
|
|
235
|
-
"int" => {
|
|
236
|
-
let val = p.extract::<i32>().unwrap();
|
|
237
|
-
SerializedValue {
|
|
238
|
-
val: Some(Val::Number(val)),
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
"float" => {
|
|
242
|
-
let val = p.extract::<f32>().unwrap();
|
|
243
|
-
SerializedValue {
|
|
244
|
-
// file: Some(File {
|
|
245
|
-
val: Some(Val::Float(val)),
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
"str" => {
|
|
249
|
-
let val = p.extract::<String>().unwrap();
|
|
250
|
-
SerializedValue {
|
|
251
|
-
val: Some(Val::String(val)),
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
"bool" => {
|
|
255
|
-
let val = p.extract::<bool>().unwrap();
|
|
256
|
-
SerializedValue {
|
|
257
|
-
val: Some(Val::Boolean(val)),
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
"list" => {
|
|
261
|
-
let list = p.downcast::<PyList>().unwrap();
|
|
262
|
-
let arr = list
|
|
263
|
-
.iter()
|
|
264
|
-
.map(|item| pyany_to_serialized_value(item))
|
|
265
|
-
.collect();
|
|
266
|
-
SerializedValue {
|
|
267
|
-
val: Some(Val::Array(SerializedValueArray { values: arr } )),
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
"dict" => {
|
|
271
|
-
let dict = p.downcast::<PyDict>().unwrap();
|
|
272
|
-
let mut map = HashMap::new();
|
|
273
|
-
for (key, value) in dict {
|
|
274
|
-
let key_string = key.extract::<String>().unwrap();
|
|
275
|
-
map.insert(key_string, pyany_to_serialized_value(value));
|
|
276
|
-
}
|
|
277
|
-
SerializedValue {
|
|
278
|
-
val: Some(Val::Object(SerializedValueObject { values: map })),
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
_ => SerializedValue::default(),
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
Err(_) => SerializedValue::default(),
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
use pyo3::prelude::*;
|
|
290
|
-
use pyo3::types::IntoPyDict;
|
|
291
|
-
use serde_json::json;
|
|
292
|
-
|
|
293
|
-
fn py_to_json<'p>(py: Python<'p>, v: &PyAny) -> serde_json::Value {
|
|
294
|
-
if v.is_none() {
|
|
295
|
-
json!(null)
|
|
296
|
-
} else if let Ok(b) = v.extract::<bool>() {
|
|
297
|
-
json!(b)
|
|
298
|
-
} else if let Ok(i) = v.extract::<i64>() {
|
|
299
|
-
json!(i)
|
|
300
|
-
} else if let Ok(f) = v.extract::<f64>() {
|
|
301
|
-
json!(f)
|
|
302
|
-
} else if let Ok(dict) = v.extract::<HashMap<String, Py<PyAny>>>() {
|
|
303
|
-
let mut m = serde_json::map::Map::new();
|
|
304
|
-
for (key, value) in dict {
|
|
305
|
-
m.insert(key, py_to_json(py, value.as_ref(py)));
|
|
306
|
-
}
|
|
307
|
-
json!(m)
|
|
308
|
-
} else if let Ok(list) = v.extract::<Vec<Py<PyAny>>>() {
|
|
309
|
-
let v: Vec<serde_json::Value> = list.iter().map(|p| py_to_json(py, p.as_ref(py))).collect();
|
|
310
|
-
json!(v)
|
|
311
|
-
} else if let Ok(s) = v.extract::<String>() {
|
|
312
|
-
json!(s)
|
|
313
|
-
} else {
|
|
314
|
-
json!(null)
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
fn dict_to_paths<'p>(
|
|
321
|
-
py: Python<'p>,
|
|
322
|
-
d: &'p PyDict
|
|
323
|
-
) -> PyResult<Vec<(Vec<String>, SerializedValue)>> {
|
|
324
|
-
let mut paths = Vec::new();
|
|
325
|
-
let mut queue: VecDeque<(Vec<String>, &'p PyDict)> = VecDeque::new();
|
|
326
|
-
queue.push_back((Vec::new(), d));
|
|
327
|
-
|
|
328
|
-
while let Some((mut path, dict)) = queue.pop_front() {
|
|
329
|
-
for (key, val) in dict {
|
|
330
|
-
let key_str = key.extract::<String>()?;
|
|
331
|
-
path.push(key_str.clone());
|
|
332
|
-
match val.downcast::<PyDict>() {
|
|
333
|
-
Ok(sub_dict) => {
|
|
334
|
-
queue.push_back((path.clone(), sub_dict));
|
|
335
|
-
},
|
|
336
|
-
Err(_) => {
|
|
337
|
-
paths.push((path.clone(), pyany_to_serialized_value(val)));
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
path.pop();
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
Ok(paths)
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
#[derive(Debug)]
|
|
349
|
-
pub struct NodeWillExecuteOnBranchWrapper(NodeWillExecuteOnBranch);
|
|
350
|
-
|
|
351
|
-
impl ToPyObject for NodeWillExecuteOnBranchWrapper {
|
|
352
|
-
fn to_object(&self, py: Python<'_>) -> PyObject {
|
|
353
|
-
let NodeWillExecuteOnBranch { branch, counter, node, custom_node_type_name} = &self.0;
|
|
354
|
-
let dict = PyDict::new(py);
|
|
355
|
-
dict.set_item("branch", branch).unwrap();
|
|
356
|
-
dict.set_item("counter", counter).unwrap();
|
|
357
|
-
if let Some(node) = node {
|
|
358
|
-
dict.set_item("node_name", &node.source_node).unwrap();
|
|
359
|
-
dict.set_item("type_name", &custom_node_type_name).unwrap();
|
|
360
|
-
|
|
361
|
-
let event_dict = PyDict::new(py);
|
|
362
|
-
// TODO: this needs to be fixed
|
|
363
|
-
for change in &node.change_values_used_in_execution {
|
|
364
|
-
if let Some(v) = &change.change_value {
|
|
365
|
-
match v {
|
|
366
|
-
ChangeValue { path: Some(path), value: Some(value), .. } => {
|
|
367
|
-
add_to_dict(
|
|
368
|
-
py,
|
|
369
|
-
&path.address,
|
|
370
|
-
SerializedValueWrapper(value.clone()).to_object(py),
|
|
371
|
-
&event_dict,
|
|
372
|
-
).unwrap();
|
|
373
|
-
},
|
|
374
|
-
_ => {}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
dict.set_item("event", event_dict).unwrap();
|
|
380
|
-
}
|
|
381
|
-
dict.into_py(py)
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
pub struct PyRespondPollNodeWillExecuteEvents(Response<RespondPollNodeWillExecuteEvents>);
|
|
386
|
-
|
|
387
|
-
impl IntoPy<Py<PyAny>> for PyRespondPollNodeWillExecuteEvents {
|
|
388
|
-
fn into_py(self, py: Python) -> Py<PyAny> {
|
|
389
|
-
let PyRespondPollNodeWillExecuteEvents(resp) = self;
|
|
390
|
-
let res = resp.into_inner();
|
|
391
|
-
let RespondPollNodeWillExecuteEvents { node_will_execute_events } = res;
|
|
392
|
-
let x: Vec<NodeWillExecuteOnBranchWrapper> = node_will_execute_events.iter().cloned().map(NodeWillExecuteOnBranchWrapper).collect();
|
|
393
|
-
PyList::new(py, x).into_py(py)
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
async fn get_client(url: String) -> Result<ExecutionRuntimeClient<tonic::transport::Channel>, PyErrWrapper> {
|
|
399
|
-
ExecutionRuntimeClient::connect(url.clone()).await.map_err(PyErrWrapper::from)
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// TODO: return a handle to nodes so that we can understand and inspect them
|
|
403
|
-
// TODO: include a __repr__ method on those nodes
|
|
404
|
-
|
|
405
|
-
#[derive(Clone)]
|
|
406
|
-
#[pyclass(name="NodeHandle")]
|
|
407
|
-
struct PyNodeHandle {
|
|
408
|
-
n: NodeHandle,
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
impl PyNodeHandle {
|
|
412
|
-
fn from(node_handle: NodeHandle) -> anyhow::Result<PyNodeHandle> {
|
|
413
|
-
Ok(PyNodeHandle { n: node_handle })
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
#[pymethods]
|
|
418
|
-
impl PyNodeHandle {
|
|
419
|
-
fn get_name(&self) -> String {
|
|
420
|
-
self.n.get_name()
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/// This updates the definition of this node to query for the target NodeHandle's output. Moving forward
|
|
424
|
-
/// it will execute whenever the target node resolves.
|
|
425
|
-
fn run_when<'a>(mut self_: PyRefMut<'_, Self>, py: Python<'a>, graph_builder: &mut PyGraphBuilder, other_node_handle: PyNodeHandle) -> PyResult<&'a PyAny> {
|
|
426
|
-
let mut n = self_.n.clone();
|
|
427
|
-
let g = Arc::clone(&graph_builder.g);
|
|
428
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
429
|
-
let mut graph_builder = g.lock().await;
|
|
430
|
-
Ok(n.run_when(&mut graph_builder, &other_node_handle.n)
|
|
431
|
-
.map_err(AnyhowErrWrapper)?)
|
|
432
|
-
})
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// #[pyo3(signature = (branch=0, frame=0))]
|
|
436
|
-
// fn query<'a>(mut self_: PyRefMut<'_, Self>, py: Python<'a>, file_id: String, url: String, branch: u64, frame: u64) -> PyResult<&'a PyAny> {
|
|
437
|
-
// pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
438
|
-
// Ok(PyQueryAtFrameResponse(self_.n.query(file_id, url, branch, frame)
|
|
439
|
-
// .await.map_err(PyErrWrapper::from)?))
|
|
440
|
-
// })
|
|
441
|
-
// }
|
|
442
|
-
|
|
443
|
-
fn __str__(&self) -> PyResult<String> {
|
|
444
|
-
// TODO: best practice is that these could be used to re-construct the same object
|
|
445
|
-
let name = self.get_name();
|
|
446
|
-
Ok(format!("NodeHandle(node={})", name))
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
fn __repr__(&self) -> PyResult<String> {
|
|
450
|
-
let name = self.get_name();
|
|
451
|
-
Ok(format!("NodeHandle(node={})", name))
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
// TODO: all operations only apply to a specific branch at a time
|
|
457
|
-
// TODO: maintain an internal map of the generated change responses for node additions to the associated query necessary to get that result
|
|
458
|
-
#[pyclass(name="Chidori")]
|
|
459
|
-
struct PyChidori {
|
|
460
|
-
c: Arc<Mutex<Chidori>>,
|
|
461
|
-
file_id: String,
|
|
462
|
-
current_head: u64,
|
|
463
|
-
current_branch: u64,
|
|
464
|
-
url: String
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// TODO: internally all operations should have an assigned counter
|
|
468
|
-
// we can keep the actual target counter hidden from the host sdk
|
|
469
|
-
#[pymethods]
|
|
470
|
-
impl PyChidori {
|
|
471
|
-
|
|
472
|
-
#[new]
|
|
473
|
-
#[pyo3(signature = (file_id=String::from("0"), url=String::from("http://127.0.0.1:9800"), api_token=None))]
|
|
474
|
-
fn new(file_id: String, url: String, api_token: Option<String>) -> Self {
|
|
475
|
-
debug!("Creating new Chidori instance with file_id={}, url={}, api_token={:?}", file_id, url, api_token);
|
|
476
|
-
let c = Chidori::new(file_id.clone(), url.clone());
|
|
477
|
-
PyChidori {
|
|
478
|
-
c: Arc::new(Mutex::new(c)),
|
|
479
|
-
file_id,
|
|
480
|
-
current_head: 0,
|
|
481
|
-
current_branch: 0,
|
|
482
|
-
url,
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
fn start_server<'a>(mut self_: PyRefMut<'_, Self>, py: Python<'a>, file_path: Option<String>) -> PyResult<&'a PyAny> {
|
|
487
|
-
let c = Arc::clone(&self_.c);
|
|
488
|
-
let url = self_.url.clone();
|
|
489
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
490
|
-
let c = c.lock().await;
|
|
491
|
-
c.start_server(file_path).await.map_err(AnyhowErrWrapper)?;
|
|
492
|
-
Ok(())
|
|
493
|
-
})
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
#[pyo3(signature = (branch=0, frame=0))]
|
|
497
|
-
fn play<'a>(mut self_: PyRefMut<'_, Self>, py: Python<'a>, branch: u64, frame: u64) -> PyResult<&'a PyAny> {
|
|
498
|
-
let file_id = self_.file_id.clone();
|
|
499
|
-
let url = self_.url.clone();
|
|
500
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
501
|
-
let mut client = get_client(url).await?;
|
|
502
|
-
Ok(PyResponseExecutionStatus(client.play(RequestAtFrame {
|
|
503
|
-
id: file_id,
|
|
504
|
-
frame,
|
|
505
|
-
branch,
|
|
506
|
-
}).await.map_err(PyErrWrapper::from)?))
|
|
507
|
-
})
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
#[pyo3(signature = (frame=0))]
|
|
512
|
-
fn pause<'a>(mut self_: PyRefMut<'_, Self>, py: Python<'a>, frame: u64) -> PyResult<&'a PyAny> {
|
|
513
|
-
let file_id = self_.file_id.clone();
|
|
514
|
-
let url = self_.url.clone();
|
|
515
|
-
let branch = self_.current_branch.clone();
|
|
516
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
517
|
-
let mut client = get_client(url).await?;
|
|
518
|
-
Ok(PyResponseExecutionStatus(client.pause(RequestAtFrame {
|
|
519
|
-
id: file_id,
|
|
520
|
-
frame,
|
|
521
|
-
branch,
|
|
522
|
-
}).await.map_err(PyErrWrapper::from)?))
|
|
523
|
-
})
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
fn branch<'a>(mut self_: PyRefMut<'_, Self>, py: Python<'a>) -> PyResult<&'a PyAny> {
|
|
528
|
-
let file_id = self_.file_id.clone();
|
|
529
|
-
let url = self_.url.clone();
|
|
530
|
-
let branch = self_.current_branch.clone();
|
|
531
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
532
|
-
let mut client = get_client(url).await?;
|
|
533
|
-
let result_branch = client.branch(RequestNewBranch {
|
|
534
|
-
id: file_id,
|
|
535
|
-
source_branch_id: branch,
|
|
536
|
-
diverges_at_counter: 0,
|
|
537
|
-
}).await.map_err(PyErrWrapper::from)?;
|
|
538
|
-
// TODO: need to somehow handle writing to the current_branch
|
|
539
|
-
Ok(PyResponseExecutionStatus(result_branch))
|
|
540
|
-
})
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
#[pyo3(signature = (query=String::new(), branch=0, frame=0))]
|
|
544
|
-
fn query<'a>(mut self_: PyRefMut<'_, Self>, py: Python<'a>, query: String, branch: u64, frame: u64) -> PyResult<&'a PyAny> {
|
|
545
|
-
let file_id = self_.file_id.clone();
|
|
546
|
-
let url = self_.url.clone();
|
|
547
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
548
|
-
let mut client = get_client(url).await?;
|
|
549
|
-
Ok(PyQueryAtFrameResponse(client.run_query(QueryAtFrame {
|
|
550
|
-
id: file_id,
|
|
551
|
-
query: Some(Query {
|
|
552
|
-
query: Some(query)
|
|
553
|
-
}),
|
|
554
|
-
frame,
|
|
555
|
-
branch,
|
|
556
|
-
}).await.map_err(PyErrWrapper::from)?))
|
|
557
|
-
})
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
fn list_branches<'a>(mut self_: PyRefMut<'_, Self>, py: Python<'a>) -> PyResult<&'a PyAny> {
|
|
561
|
-
let file_id = self_.file_id.clone();
|
|
562
|
-
let url = self_.url.clone();
|
|
563
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
564
|
-
let mut client = get_client(url).await?;
|
|
565
|
-
Ok(PyListBranchesRes(client.list_branches(RequestListBranches {
|
|
566
|
-
id: file_id,
|
|
567
|
-
}).await.map_err(PyErrWrapper::from)?))
|
|
568
|
-
})
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
fn display_graph_structure<'a>(
|
|
572
|
-
mut self_: PyRefMut<'_, Self>,
|
|
573
|
-
py: Python<'a>
|
|
574
|
-
) -> PyResult<&'a PyAny> {
|
|
575
|
-
let file_id = self_.file_id.clone();
|
|
576
|
-
let url = self_.url.clone();
|
|
577
|
-
let branch = self_.current_branch.clone();
|
|
578
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
579
|
-
let mut client = get_client(url).await?;
|
|
580
|
-
let file = client.current_file_state(RequestOnlyId {
|
|
581
|
-
id: file_id,
|
|
582
|
-
branch
|
|
583
|
-
}).await.map_err(PyErrWrapper::from)?;
|
|
584
|
-
let mut file = file.into_inner();
|
|
585
|
-
let mut g = CleanedDefinitionGraph::zero();
|
|
586
|
-
g.merge_file(&mut file).unwrap();
|
|
587
|
-
Ok(g.get_dot_graph())
|
|
588
|
-
})
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
// TODO: some of these register handlers instead
|
|
592
|
-
// TODO: list registered graphs should not stream
|
|
593
|
-
// TODO: add a message that sends the current graph state
|
|
594
|
-
|
|
595
|
-
fn list_registered_graphs<'a>(
|
|
596
|
-
mut self_: PyRefMut<'_, Self>,
|
|
597
|
-
py: Python<'a>
|
|
598
|
-
) -> PyResult<&'a PyAny> {
|
|
599
|
-
let file_id = self_.file_id.clone();
|
|
600
|
-
let url = self_.url.clone();
|
|
601
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
602
|
-
let mut client = get_client(url).await?;
|
|
603
|
-
let resp = client.list_registered_graphs(Empty {
|
|
604
|
-
}).await.map_err(PyErrWrapper::from)?;
|
|
605
|
-
let mut stream = resp.into_inner();
|
|
606
|
-
while let Some(x) = stream.next().await {
|
|
607
|
-
// callback.call(py, (x,), None);
|
|
608
|
-
info!("Registered Graph = {:?}", x);
|
|
609
|
-
};
|
|
610
|
-
Ok(())
|
|
611
|
-
})
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
fn list_input_proposals<'a>(
|
|
615
|
-
mut self_: PyRefMut<'_, Self>,
|
|
616
|
-
py: Python<'a>,
|
|
617
|
-
callback: PyObject
|
|
618
|
-
) -> PyResult<&'a PyAny> {
|
|
619
|
-
let file_id = self_.file_id.clone();
|
|
620
|
-
let url = self_.url.clone();
|
|
621
|
-
let branch = self_.current_branch;
|
|
622
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
623
|
-
let mut client = get_client(url).await?;
|
|
624
|
-
let resp = client.list_input_proposals(RequestOnlyId {
|
|
625
|
-
id: file_id,
|
|
626
|
-
branch,
|
|
627
|
-
}).await.map_err(PyErrWrapper::from)?;
|
|
628
|
-
let mut stream = resp.into_inner();
|
|
629
|
-
while let Some(x) = stream.next().await {
|
|
630
|
-
// callback.call(py, (x,), None);
|
|
631
|
-
info!("InputProposals = {:?}", x);
|
|
632
|
-
};
|
|
633
|
-
Ok(())
|
|
634
|
-
})
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
// fn respond_to_input_proposal(mut self_: PyRefMut<'_, Self>) -> PyResult<()> {
|
|
638
|
-
// Ok(())
|
|
639
|
-
// }
|
|
640
|
-
|
|
641
|
-
// TODO: this is a successful callback example
|
|
642
|
-
fn list_change_events<'a>(
|
|
643
|
-
mut self_: PyRefMut<'_, Self>,
|
|
644
|
-
py: Python<'a>,
|
|
645
|
-
callback: PyObject
|
|
646
|
-
) -> PyResult<&'a PyAny> {
|
|
647
|
-
let file_id = self_.file_id.clone();
|
|
648
|
-
let url = self_.url.clone();
|
|
649
|
-
let branch = self_.current_branch;
|
|
650
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
651
|
-
let mut client = get_client(url).await?;
|
|
652
|
-
let resp = client.list_change_events(RequestOnlyId {
|
|
653
|
-
id: file_id,
|
|
654
|
-
branch,
|
|
655
|
-
}).await.map_err(PyErrWrapper::from)?;
|
|
656
|
-
let mut stream = resp.into_inner();
|
|
657
|
-
while let Some(x) = stream.next().await {
|
|
658
|
-
Python::with_gil(|py| pyo3_asyncio::tokio::into_future(callback.as_ref(py).call((x.map(ChangeValueWithCounterWrapper).map_err(PyErrWrapper::from)?,), None)?))?
|
|
659
|
-
.await?;
|
|
660
|
-
};
|
|
661
|
-
Ok(())
|
|
662
|
-
})
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
pub fn register_custom_node_handle<'a>(
|
|
666
|
-
mut self_: PyRefMut<'_, Self>,
|
|
667
|
-
py: Python<'a>,
|
|
668
|
-
key: String,
|
|
669
|
-
handler: PyObject
|
|
670
|
-
) -> PyResult<&'a PyAny> {
|
|
671
|
-
let c = Arc::clone(&self_.c);
|
|
672
|
-
let handler = Arc::new(handler);
|
|
673
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
674
|
-
let mut c = c.lock().await;
|
|
675
|
-
c.register_custom_node_handle(key, Handler::new(
|
|
676
|
-
move |n| {
|
|
677
|
-
let handler_clone = Arc::clone(&handler);
|
|
678
|
-
Box::pin(async move {
|
|
679
|
-
let result = Python::with_gil(|py| {
|
|
680
|
-
let fut = handler_clone.as_ref().call(py, (NodeWillExecuteOnBranchWrapper(n).to_object(py), ), None)?;
|
|
681
|
-
pyo3_asyncio::tokio::into_future(fut.as_ref(py))
|
|
682
|
-
})?.await;
|
|
683
|
-
match result {
|
|
684
|
-
Ok(py_obj) => {
|
|
685
|
-
Python::with_gil(|py| {
|
|
686
|
-
let json_value = py_to_json(py, py_obj.as_ref(py));
|
|
687
|
-
Ok(json_value)
|
|
688
|
-
})
|
|
689
|
-
},
|
|
690
|
-
Err(err) => Err(anyhow::Error::new(err)),
|
|
691
|
-
}
|
|
692
|
-
})
|
|
693
|
-
}
|
|
694
|
-
));
|
|
695
|
-
Ok(())
|
|
696
|
-
})
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
fn run_custom_node_loop<'a>(
|
|
700
|
-
mut self_: PyRefMut<'_, Self>,
|
|
701
|
-
py: Python<'a>,
|
|
702
|
-
) -> PyResult<&'a PyAny> {
|
|
703
|
-
let c = Arc::clone(&self_.c);
|
|
704
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
705
|
-
let mut c = c.lock().await;
|
|
706
|
-
Ok(c.run_custom_node_loop().await.map_err(AnyhowErrWrapper)?)
|
|
707
|
-
})
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
//
|
|
712
|
-
// fn observation_node(mut self_: PyRefMut<'_, Self>, name: String, query_def: Option<String>, template: String, model: String) -> PyResult<()> {
|
|
713
|
-
// let file_id = self_.file_id.clone();
|
|
714
|
-
// let node = create_observation_node(
|
|
715
|
-
// "".to_string(),
|
|
716
|
-
// None,
|
|
717
|
-
// "".to_string(),
|
|
718
|
-
// );
|
|
719
|
-
// executor::block_on(self_.client.merge(RequestFileMerge {
|
|
720
|
-
// id: file_id,
|
|
721
|
-
// file: Some(File {
|
|
722
|
-
// nodes: vec![node],
|
|
723
|
-
// ..Default::default()
|
|
724
|
-
// }),
|
|
725
|
-
// branch: 0,
|
|
726
|
-
// }));
|
|
727
|
-
// Ok(())
|
|
728
|
-
// }
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
#[pyclass(name="GraphBuilder")]
|
|
732
|
-
#[derive(Clone)]
|
|
733
|
-
struct PyGraphBuilder {
|
|
734
|
-
g: Arc<Mutex<GraphBuilder>>,
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
#[pymethods]
|
|
738
|
-
impl PyGraphBuilder {
|
|
739
|
-
|
|
740
|
-
#[new]
|
|
741
|
-
fn new() -> Self {
|
|
742
|
-
let g = GraphBuilder::new();
|
|
743
|
-
PyGraphBuilder {
|
|
744
|
-
g: Arc::new(Mutex::new(g)),
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
// https://github.com/PyO3/pyo3/issues/525
|
|
749
|
-
#[pyo3(signature = (name=String::new(), queries=vec!["None".to_string()], output_tables=vec![], output=String::from("{}"), node_type_name=String::new()))]
|
|
750
|
-
fn custom_node<'a>(
|
|
751
|
-
mut self_: PyRefMut<'_, Self>,
|
|
752
|
-
py: Python<'a>,
|
|
753
|
-
name: String,
|
|
754
|
-
queries: Option<Vec<String>>,
|
|
755
|
-
output_tables: Vec<String>,
|
|
756
|
-
output: String,
|
|
757
|
-
node_type_name: String,
|
|
758
|
-
) -> PyResult<&'a PyAny> {
|
|
759
|
-
let g = Arc::clone(&self_.g);
|
|
760
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
761
|
-
let mut graph_builder = g.lock().await;
|
|
762
|
-
let nh = graph_builder.custom_node(CustomNodeCreateOpts {
|
|
763
|
-
name,
|
|
764
|
-
queries,
|
|
765
|
-
output_tables: Some(output_tables),
|
|
766
|
-
output: Some(output),
|
|
767
|
-
node_type_name,
|
|
768
|
-
}).map_err(AnyhowErrWrapper)?;
|
|
769
|
-
Ok(PyNodeHandle::from(nh).map_err(AnyhowErrWrapper)?)
|
|
770
|
-
})
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
#[pyo3(signature = (name=String::new(), queries=vec!["None".to_string()], output_tables=None, output=None, code=String::new(), is_template=None))]
|
|
774
|
-
fn deno_code_node<'a>(
|
|
775
|
-
mut self_: PyRefMut<'_, Self>,
|
|
776
|
-
py: Python<'a>,
|
|
777
|
-
name: String,
|
|
778
|
-
queries: Option<Vec<String>>,
|
|
779
|
-
output_tables: Option<Vec<String>>,
|
|
780
|
-
output: Option<String>,
|
|
781
|
-
code: String,
|
|
782
|
-
is_template: Option<bool>
|
|
783
|
-
) -> PyResult<&'a PyAny> {
|
|
784
|
-
let g = Arc::clone(&self_.g);
|
|
785
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
786
|
-
let mut graph_builder = g.lock().await;
|
|
787
|
-
let nh = graph_builder.deno_code_node(DenoCodeNodeCreateOpts {
|
|
788
|
-
name,
|
|
789
|
-
queries,
|
|
790
|
-
output_tables,
|
|
791
|
-
output,
|
|
792
|
-
code,
|
|
793
|
-
is_template,
|
|
794
|
-
}).map_err(AnyhowErrWrapper)?;
|
|
795
|
-
Ok(PyNodeHandle::from(nh).map_err(AnyhowErrWrapper)?)
|
|
796
|
-
})
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
#[pyo3(signature = (name=String::new(), queries=vec!["None".to_string()], output_tables=vec![], output=String::from("{}"), template=String::new(), action="WRITE".to_string(), embedding_model="TEXT_EMBEDDING_ADA_002".to_string(), db_vendor="QDRANT".to_string(), collection_name=String::new()))]
|
|
801
|
-
fn vector_memory_node<'a>(
|
|
802
|
-
mut self_: PyRefMut<'_, Self>,
|
|
803
|
-
py: Python<'a>,
|
|
804
|
-
name: String,
|
|
805
|
-
queries: Option<Vec<String>>,
|
|
806
|
-
output_tables: Vec<String>,
|
|
807
|
-
output: String,
|
|
808
|
-
template: String,
|
|
809
|
-
action: String, // READ / WRITE
|
|
810
|
-
embedding_model: String,
|
|
811
|
-
db_vendor: String,
|
|
812
|
-
collection_name: String,
|
|
813
|
-
) -> PyResult<&'a PyAny> {
|
|
814
|
-
let g = Arc::clone(&self_.g);
|
|
815
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
816
|
-
let mut graph_builder = g.lock().await;
|
|
817
|
-
let nh = graph_builder.vector_memory_node(VectorMemoryNodeCreateOpts {
|
|
818
|
-
name,
|
|
819
|
-
queries,
|
|
820
|
-
output_tables: Some(output_tables),
|
|
821
|
-
output: Some(output),
|
|
822
|
-
template: Some(template),
|
|
823
|
-
action: Some(action),
|
|
824
|
-
embedding_model: Some(embedding_model),
|
|
825
|
-
db_vendor: Some(db_vendor),
|
|
826
|
-
collection_name,
|
|
827
|
-
}).map_err(AnyhowErrWrapper)?;
|
|
828
|
-
Ok(PyNodeHandle::from(nh).map_err(AnyhowErrWrapper)?)
|
|
829
|
-
})
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
// // TODO: nodes that are added should return a clean definition of what their addition looks like
|
|
834
|
-
// // TODO: adding a node should also display any errors
|
|
835
|
-
// /// x = None
|
|
836
|
-
// /// with open("/Users/coltonpierson/Downloads/files_and_dirs.zip", "rb") as zip_file:
|
|
837
|
-
// /// contents = zip_file.read()
|
|
838
|
-
// /// x = await p.load_zip_file("LoadZip", """ output: String """, contents)
|
|
839
|
-
// /// x
|
|
840
|
-
// #[pyo3(signature = (name=String::new(), output_tables=vec![], output=String::new(), bytes=vec![]))]
|
|
841
|
-
// fn load_zip_file<'a>(
|
|
842
|
-
// mut self_: PyRefMut<'_, Self>,
|
|
843
|
-
// py: Python<'a>,
|
|
844
|
-
// name: String,
|
|
845
|
-
// output_tables: Vec<String>,
|
|
846
|
-
// output: String,
|
|
847
|
-
// bytes: Vec<u8>
|
|
848
|
-
// ) -> PyResult<&'a PyAny> {
|
|
849
|
-
// let file_id = self_.file_id.clone();
|
|
850
|
-
// let url = self_.url.clone();
|
|
851
|
-
// pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
852
|
-
// let node = create_loader_node(
|
|
853
|
-
// name,
|
|
854
|
-
// vec![],
|
|
855
|
-
// output,
|
|
856
|
-
// LoadFrom::ZipfileBytes(bytes),
|
|
857
|
-
// output_tables
|
|
858
|
-
// );
|
|
859
|
-
// Ok(push_file_merge(&url, &file_id, node).await?)
|
|
860
|
-
// })
|
|
861
|
-
// }
|
|
862
|
-
|
|
863
|
-
// TODO: nodes that are added should return a clean definition of what their addition looks like
|
|
864
|
-
// TODO: adding a node should also display any errors
|
|
865
|
-
#[pyo3(signature = (name=String::new(), queries=vec!["None".to_string()], output_tables=None, template=String::new(), model=None))]
|
|
866
|
-
fn prompt_node<'a>(
|
|
867
|
-
mut self_: PyRefMut<'_, Self>,
|
|
868
|
-
py: Python<'a>,
|
|
869
|
-
name: String,
|
|
870
|
-
queries: Option<Vec<String>>,
|
|
871
|
-
output_tables: Option<Vec<String>>,
|
|
872
|
-
template: String,
|
|
873
|
-
model: Option<String>
|
|
874
|
-
) -> PyResult<&'a PyAny> {
|
|
875
|
-
let g = Arc::clone(&self_.g);
|
|
876
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
877
|
-
let mut graph_builder = g.lock().await;
|
|
878
|
-
let nh = graph_builder.prompt_node(PromptNodeCreateOpts {
|
|
879
|
-
name,
|
|
880
|
-
queries,
|
|
881
|
-
output_tables,
|
|
882
|
-
template,
|
|
883
|
-
model,
|
|
884
|
-
}).map_err(AnyhowErrWrapper)?;
|
|
885
|
-
Ok(PyNodeHandle::from(nh).map_err(AnyhowErrWrapper)?)
|
|
886
|
-
})
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
fn commit<'a>(
|
|
890
|
-
mut self_: PyRefMut<'_, Self>,
|
|
891
|
-
py: Python<'a>,
|
|
892
|
-
c: PyRef<'_, PyChidori>,
|
|
893
|
-
branch: u64
|
|
894
|
-
) -> PyResult<&'a PyAny> {
|
|
895
|
-
let g = Arc::clone(&self_.g);
|
|
896
|
-
let c = Arc::clone(&c.c);
|
|
897
|
-
pyo3_asyncio::tokio::future_into_py(py, async move {
|
|
898
|
-
let mut graph_builder = g.lock().await;
|
|
899
|
-
let mut chidori = c.lock().await;
|
|
900
|
-
let exec_status = graph_builder.commit(&chidori, branch).await
|
|
901
|
-
.map(PyExecutionStatus)
|
|
902
|
-
.map_err(AnyhowErrWrapper)?;
|
|
903
|
-
Ok(exec_status)
|
|
904
|
-
})
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
/// A Python module implemented in Rust. The name of this function must match
|
|
910
|
-
/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to
|
|
911
|
-
/// import the module.
|
|
912
|
-
#[pymodule]
|
|
913
|
-
#[pyo3(name = "_chidori")]
|
|
914
|
-
fn chidori(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|
915
|
-
// pyo3_log::init();
|
|
916
|
-
m.add_class::<PyChidori>()?;
|
|
917
|
-
m.add_class::<PyGraphBuilder>()?;
|
|
918
|
-
m.add_class::<PyNodeHandle>()?;
|
|
919
|
-
Ok(())
|
|
920
|
-
}
|
|
921
|
-
|