Skip to content

Commit c96c902

Browse files
committed
hono web server in js cell functioning correctly
1 parent 516fe49 commit c96c902

File tree

113 files changed

+5880
-968
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+5880
-968
lines changed

README.md

+17-17
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,18 @@ Chidori is an open-source orchestrator, runtime, and IDE for building software i
4343
It is especially catered towards building AI agents by providing solutions to the following problems:
4444

4545
- How do we understand what an agent is doing and how it got into a given state?
46-
- How can we pause execution and then resume after human review?
46+
- How can we pause execution and then resume after interaction with a human?
4747
- How do we handle the accidental complexity of state-space exploration, evaluating and reverting execution throughout our software?
4848

49-
When using Chidori, you author code with python or javascript, and we provide a layer for interfacing
49+
When using Chidori, you author code with python or javascript, we provide a layer for interfacing
5050
with the complexities of AI models in long-running workflows. We have avoided the need for declaring a new language
51-
or SDK in order to provide these capabilities, you can leverage software patterns that you are already familiar with.
51+
or SDK in order to provide these capabilities so that you can leverage software patterns that you are already familiar with.
5252

5353
Features:
5454

5555
- Runtime written in Rust, supporting Python and JavaScript code execution
56-
- Cache behaviors and resume from partially executed agents
57-
- Time travel debugging, revert to prior states of execution
56+
- The ability to cache behaviors and resume from partially executed agents
57+
- Time travel debugging, execution of the program can be reverted to prior states
5858
- Visual debugging environment, visualize and manipulate the graph of states your code has executed through.
5959
- Create and navigate tree-searching code execution workflows
6060

@@ -70,23 +70,22 @@ prototype development is `chidori-debugger` which wraps our runtime in a useful
7070

7171
```bash
7272
xcode-select --install
73-
brew install cmake
7473

74+
# These dependencies are necessary for a successful build
75+
brew install \
76+
cmake \
7577
# Protobuf is depended upon by denokv, which we in turn currently depend on
76-
brew install protobuf
77-
78+
protobuf \
7879
# We are investigating if this is necessary or can be removed
79-
brew install libiconv
80-
81-
brew install [email protected]
82-
80+
libiconv \
81+
8382
# Chidori uses uv for handling python dependencies
84-
brew install uv
83+
uv
8584

8685
cargo install chidori-debugger
8786
```
8887

89-
If you would prefer a different python interpreter you can set PYO3_PYTHON=python3.12 (or whichever version > 3.7) during
88+
If you prefer to use a different python interpreter you can set PYO3_PYTHON=python3.12 (or whichever version > 3.7) during
9089
your installation to change which is linked against.
9190

9291

@@ -95,8 +94,9 @@ Chidori's interactions with LLMs default to http://localhost:4000 to hook into L
9594
If you'd like to leverage gpt-3.5-turbo the included config file will support that.
9695
You will need to install `pip install litellm[proxy]` in order to run the below:
9796
```bash
97+
uv sync
9898
export OPENAI_API_KEY=...
99-
litellm --config ./litellm_config.yaml
99+
uv run litellm --config ./litellm_config.yaml
100100
```
101101

102102
## Examples
@@ -214,7 +214,7 @@ Our framework is inspired by the work of many others, including:
214214
* [Langchain](https://www.langchain.com) - developing tools and patterns for building with LLMs
215215

216216
## License
217-
Thousand Birds is under the MIT license. See the [LICENSE](LICENSE) for more information.
217+
Chidori is under the MIT license. See the [LICENSE](LICENSE) for more information.
218218

219219
## Help us out!
220-
Please star the github repo and give us feedback in [discord](https://discord.gg/CJwKsPSgew)!
220+
Please star the GitHub repo and give us feedback in [discord](https://discord.gg/CJwKsPSgew)!

toolchain/book_src/ARCHITECTURE.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
Chidori consists of the following crates:
66

7-
- `chidori-core` contains our orchestator and runtime.
7+
- `chidori-core` contains our orchestrator and runtime.
88
- `chidori-debugger` contains a UI for visualizing and debugging Chidori executed programs.
99
- `chidori-im-rs` contains a fork of im-rs to add support for persisting these data structures to disk.
10-
- `chidori-prompt-format` implements handlbars-like templating with support for tracing composition
10+
- `chidori-prompt-format` implements handlebars-like templating with support for tracing composition
1111
- `chidori-static-analysis` implements our parsing and extraction of control-flow from Python and TypeScript source code
1212
- `chidori-optimizer-dsp` (IGNORE) - not yet implemented, in the future we'd like to support DSPy-like optimization
1313
- `chidori-tsne` (IGNORE) - not yet implemented, in the future we'd like to add support for visualizing embeddings within our debugger

toolchain/book_src/COMMON_ERRORS.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11

22
# Commonly Encountered Errors
33

4-
Error:
5-
ld: library 'python3.12' not found
4+
## Error: `ld: library 'python3.12' not found`
65

76
Solution:
87
Set PYO3_PYTHON=python3.11 when building chidori-debugger to your currently installed python version.

toolchain/chidori-core/examples/core11_hono/core.md

-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import { serve } from 'https://deno.land/[email protected]/http/server.ts';
66

77
const app = new Hono();
88

9-
// Middleware to parse form data
10-
app.use('/submit', bodyParser.urlencoded({ extended: true }));
11-
129
app.get('/', (c) => {
1310
const form = `
1411
<h1>Welcome to Trip Planner Crew</h1>

toolchain/chidori-core/examples/core2_marshalling/core.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Chidori.assertEq(x6, [1, 2, 3]);
3838
// TODO: marshalling of sets is not currently supported
3939
// Chidori.assertEq(x7, ["c", "b", "a"]);
4040

41-
Chidori.assertEq(x8, null);
41+
// Chidori.assertEq(x8, null);
4242

4343
// TODO: marshalling of functions is not currently supported
4444
// Chidori.assertEq(typeof x9, "function");

toolchain/chidori-core/examples/core5_prompts_invoked_as_functions/core.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
This is a python function that is invoking a prompt by name, kwargs to this
44
invocation are passed to the prompt. Prompts are async and return strings.
55
```python (run_prompt_cell)
6-
def first_letter(s):
6+
async def first_letter(s):
77
return s.replace("-", "").strip()[0]
88

99
async def run_prompt(number_of_states):
1010
out = ""
1111
for state in (await get_states_first_letters(num=number_of_states)).split('\n'):
12-
out += first_letter(state)
12+
out += await first_letter(state)
1313
return "demo" + out
1414
```
1515

toolchain/chidori-core/src/cells/code_cell.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub fn code_cell(execution_state_id: ExecutionNodeId, cell: &CodeCell, range: &T
4141
Ok(OperationFnOutput {
4242
has_error: false,
4343
execution_state: None,
44-
output: result.0,
44+
output: result.0.unwrap(),
4545
stdout: result.1,
4646
stderr: result.2,
4747
})

toolchain/chidori-core/src/execution/execution/execution_graph.rs

+24-14
Original file line numberDiff line numberDiff line change
@@ -174,17 +174,27 @@ impl ExecutionGraph {
174174
let s = resulting_execution_state.clone();
175175

176176
match resulting_execution_state {
177-
ExecutionStateEvaluation::Error => {}
178-
ExecutionStateEvaluation::EvalFailure => {}
177+
ExecutionStateEvaluation::Error(id) => {
178+
state_id_to_state.deref_mut().insert(id.clone(), s.clone());
179+
}
180+
ExecutionStateEvaluation::EvalFailure(id) => {
181+
state_id_to_state.deref_mut().insert(id.clone(), s.clone());
182+
}
179183
ExecutionStateEvaluation::Complete(state) => {
180-
println!("Adding to execution state!!!! {:?}", state.id);
184+
// println!("Adding to execution state!!!! {:?}", state.id);
181185
let resulting_state_id = state.id;
182186
state_id_to_state.deref_mut().insert(resulting_state_id.clone(), s.clone());
183187
execution_graph.deref_mut()
184188
.add_edge(state.parent_state_id, resulting_state_id.clone(), s);
185189
}
186-
ExecutionStateEvaluation::Executing(..) => {
187-
190+
ExecutionStateEvaluation::Executing(state) => {
191+
let resulting_state_id = state.id;
192+
if let Some(ExecutionStateEvaluation::Complete(_)) = state_id_to_state.deref().get(&resulting_state_id) {
193+
} else {
194+
state_id_to_state.deref_mut().insert(resulting_state_id.clone(), s.clone());
195+
execution_graph.deref_mut()
196+
.add_edge(state.parent_state_id, resulting_state_id.clone(), s);
197+
}
188198
}
189199
}
190200

@@ -233,9 +243,9 @@ impl ExecutionGraph {
233243
let mut grouped_nodes = HashSet::new();
234244
for (source, target, ev) in execution_graph.deref().all_edges() {
235245
match ev {
236-
ExecutionStateEvaluation::EvalFailure => {},
237-
ExecutionStateEvaluation::Error => {}
238-
ExecutionStateEvaluation::Executing(..) => {
246+
ExecutionStateEvaluation::EvalFailure(_) => {},
247+
ExecutionStateEvaluation::Error(_) => {}
248+
ExecutionStateEvaluation::Executing(s) => {
239249
}
240250
ExecutionStateEvaluation::Complete(s) => {
241251
if !s.stack.is_empty() {
@@ -315,8 +325,8 @@ impl ExecutionGraph {
315325
ExecutionStateEvaluation::Executing(state) =>
316326
(state.parent_state_id, state.id)
317327
,
318-
ExecutionStateEvaluation::Error => unreachable!("Cannot get state from a future state"),
319-
ExecutionStateEvaluation::EvalFailure => unreachable!("Cannot get state from a future state"),
328+
ExecutionStateEvaluation::Error(_) => unreachable!("Cannot get state from a future state"),
329+
ExecutionStateEvaluation::EvalFailure(_) => unreachable!("Cannot get state from a future state"),
320330
};
321331
println!("Inserting into graph {:?}", &resulting_state_id);
322332
// TODO: if state already exists how to handle
@@ -345,8 +355,8 @@ impl ExecutionGraph {
345355
let previous_state = match previous_state {
346356
ExecutionStateEvaluation::Complete(state) => state,
347357
ExecutionStateEvaluation::Executing(..) => panic!("Cannot step an execution state that is currently executing"),
348-
ExecutionStateEvaluation::Error => unreachable!("Cannot get state from a future state"),
349-
ExecutionStateEvaluation::EvalFailure => unreachable!("Cannot get state from a future state"),
358+
ExecutionStateEvaluation::Error(_) => unreachable!("Cannot get state from a future state"),
359+
ExecutionStateEvaluation::EvalFailure(_) => unreachable!("Cannot get state from a future state"),
350360
};
351361
let eval_state = previous_state.determine_next_operation()?;
352362
// TODO: update graph with representation that we're inside of executing something
@@ -380,8 +390,8 @@ impl ExecutionGraph {
380390
return Err(anyhow!("Cannot mutate a graph that is currently executing"))
381391
},
382392

383-
ExecutionStateEvaluation::Error => unreachable!("Cannot get state from a future state"),
384-
ExecutionStateEvaluation::EvalFailure => unreachable!("Cannot get state from a future state"),
393+
ExecutionStateEvaluation::Error(_) => unreachable!("Cannot get state from a future state"),
394+
ExecutionStateEvaluation::EvalFailure(_) => unreachable!("Cannot get state from a future state"),
385395

386396
};
387397

toolchain/chidori-core/src/execution/execution/execution_state.rs

+23-16
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,22 @@ impl Future for FutureExecutionState {
7676
}
7777
}
7878

79+
#[derive(thiserror::Error, Debug, PartialOrd, PartialEq)]
80+
pub enum ExecutionStateErrors {
81+
#[error("the execution of this graph has reached a fixed point and will not continue without outside influence")]
82+
NoFurtherExecutionDetected,
83+
#[error("an unexpected error has occurred during the evaluation of state {0}")]
84+
CellExecutionUnexpectedFailure(ExecutionNodeId, String),
85+
#[error("unknown execution state error")]
86+
Unknown(String),
87+
}
88+
7989
#[derive(Clone)]
8090
pub enum ExecutionStateEvaluation {
8191
/// An exception was thrown
82-
Error,
92+
Error(ExecutionNodeId),
8393
/// An eval function indicated that we should return
84-
EvalFailure,
94+
EvalFailure(ExecutionNodeId),
8595
/// Execution complete
8696
Complete(ExecutionState),
8797
/// Execution in progress
@@ -94,17 +104,17 @@ impl ExecutionStateEvaluation {
94104

95105
ExecutionStateEvaluation::Complete(ref state) => state.state_get(operation_id),
96106
ExecutionStateEvaluation::Executing(..) => unreachable!("Cannot get state from a future state"),
97-
ExecutionStateEvaluation::Error => unreachable!("Cannot get state from a future state"),
98-
ExecutionStateEvaluation::EvalFailure => unreachable!("Cannot get state from a future state"),
107+
ExecutionStateEvaluation::Error(_) => unreachable!("Cannot get state from a future state"),
108+
ExecutionStateEvaluation::EvalFailure(_) => unreachable!("Cannot get state from a future state"),
99109
}
100110
}
101111

102112
pub fn state_get_value(&self, operation_id: &OperationId) -> Option<&RkyvSerializedValue> {
103113
match self {
104114
ExecutionStateEvaluation::Complete(ref state) => state.state_get(operation_id).map(|o| &o.output),
105115
ExecutionStateEvaluation::Executing(..) => unreachable!("Cannot get state from a future state"),
106-
ExecutionStateEvaluation::Error => unreachable!("Cannot get state from a future state"),
107-
ExecutionStateEvaluation::EvalFailure => unreachable!("Cannot get state from a future state"),
116+
ExecutionStateEvaluation::Error(_) => unreachable!("Cannot get state from a future state"),
117+
ExecutionStateEvaluation::EvalFailure(_) => unreachable!("Cannot get state from a future state"),
108118
}
109119
}
110120
}
@@ -114,8 +124,8 @@ impl Debug for ExecutionStateEvaluation {
114124
match self {
115125
ExecutionStateEvaluation::Complete(ref state) => f.debug_tuple("Complete").field(state).finish(),
116126
ExecutionStateEvaluation::Executing(..) => f.debug_tuple("Executing").field(&format!("Future state evaluating")).finish(),
117-
ExecutionStateEvaluation::Error => unreachable!("Cannot get state from a future state"),
118-
ExecutionStateEvaluation::EvalFailure => unreachable!("Cannot get state from a future state"),
127+
ExecutionStateEvaluation::Error(_) => unreachable!("Cannot get state from a future state"),
128+
ExecutionStateEvaluation::EvalFailure(_) => unreachable!("Cannot get state from a future state"),
119129
}
120130
}
121131
}
@@ -652,14 +662,15 @@ impl ExecutionState {
652662
/// Receiver that we pass to the exec for it to capture oneshot RPC communication
653663
let exec = op.operation.deref();
654664
let result = exec(&before_execution_state, payload, None, None).await?;
655-
let mut after_execution_state = state.clone_with_new_id();
665+
666+
// Add result into a new execution state
667+
let mut after_execution_state = state.clone();
656668
after_execution_state.stack.pop_back();
657669
after_execution_state.state_insert(usize::MAX, result.clone());
658670
after_execution_state.fresh_values.insert(usize::MAX);
659671

660-
// TODO: Add result into a new execution state
661672

662-
// TODO: capture the value of the output
673+
// Capture the value of the output
663674
if let Some(graph_sender) = self.graph_sender.as_ref() {
664675
let s = graph_sender.clone();
665676
let result = pause_future_with_oneshot(ExecutionStateEvaluation::Complete(after_execution_state.clone()), &s).await;
@@ -778,16 +789,12 @@ impl ExecutionState {
778789
let dependency_graph = self.get_dependency_graph();
779790

780791
// If none of the inputs are more fresh than our own operation freshness, skip this node
781-
// TODO: order appears to matter here, and it shouldn't
782792
if !signature.is_empty() {
783793
let our_freshness = self.value_freshness_map.get(&next_operation_id).copied().unwrap_or(0);
784-
dbg!((&next_operation_id, &our_freshness));
785-
dbg!(signature);
786794
let any_more_fresh = dependency_graph
787795
.edges_directed(next_operation_id, Direction::Incoming)
788796
.any(|(from, _, _)| {
789797
let their_freshness = self.value_freshness_map.get(&from).copied().unwrap_or(0);
790-
dbg!((from, their_freshness));
791798
their_freshness >= our_freshness
792799
});
793800
if !any_more_fresh {
@@ -799,7 +806,7 @@ impl ExecutionState {
799806
let inputs = self.prepare_operation_inputs(signature, next_operation_id, dependency_graph)?;
800807

801808
if !signature.check_input_against_signature(&inputs) {
802-
println!("Signature validation failed continuing");
809+
println!("Signature validation failed, continuing");
803810
return Ok(None);
804811
}
805812

toolchain/chidori-core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ pub mod utils;
1111

1212
pub use tokio;
1313
pub use uuid;
14+
pub use chidori_static_analysis;

0 commit comments

Comments
 (0)