Skip to content

Commit 703bbb9

Browse files
committed
Merge remote-tracking branch 'origin/main'
2 parents 9208c32 + 2dca878 commit 703bbb9

20 files changed

Lines changed: 767 additions & 31 deletions

File tree

.github/workflows/rust.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Rust
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
12+
jobs:
13+
build:
14+
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
- name: Build
20+
run: cargo build --verbose
21+
- name: Run tests
22+
run: cargo test --verbose

config/pulse-default.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
colors:
2+
foreground: white
3+
background: black
4+
primary: cyan
5+
6+
widgets:
7+
textbox_prefix: "[ "
8+
textbox_suffix: " ]"
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from langchain_fireworks import ChatFireworks
2+
from langchain_core.tools import tool
3+
from langchain_core.messages import HumanMessage
4+
5+
# 1. Définir un tool simple
6+
@tool
7+
def multiply(a: int, b: int) -> int:
8+
"""Multiply two integers."""
9+
return a * b
10+
11+
12+
# 2. Initialiser le modèle
13+
llm = ChatFireworks(
14+
model="accounts/fireworks/models/minimax-m2p1",
15+
temperature=0.0,
16+
)
17+
18+
# 3. Lier les tools au modèle
19+
llm_with_tools = llm.bind_tools([multiply])
20+
21+
# 4. Message utilisateur
22+
messages = [
23+
HumanMessage(content="What is 6 times 7?")
24+
]
25+
26+
# 5. Appel du modèle
27+
response = llm_with_tools.invoke(messages)
28+
29+
# 6. Vérifier si le modèle demande un tool
30+
if response.tool_calls:
31+
for tool_call in response.tool_calls:
32+
if tool_call["name"] == "multiply":
33+
args = tool_call["args"]
34+
result = multiply.invoke(args)
35+
36+
print("Tool result:", result)
37+
38+
# 7. Réinjecter le résultat au modèle (optionnel ici)
39+
final = llm.invoke([
40+
messages[0],
41+
response,
42+
{
43+
"role": "tool",
44+
"tool_call_id": tool_call["id"],
45+
"content": str(result),
46+
}
47+
])
48+
49+
print("Final answer:", final.content)
50+
else:
51+
print("Model answer:", response.content)

src/cli.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,23 @@ pub enum Commands {
2626
Embeddings {
2727
#[arg(short = 't', long = "text")]
2828
text_path: PathBuf,
29-
#[arg(short = 'm', long = "model", default_value = "nomic-ai/nomic-embed-text-v1.5")]
29+
#[arg(
30+
short = 'm',
31+
long = "model",
32+
default_value = "nomic-ai/nomic-embed-text-v1.5"
33+
)]
3034
model: String,
3135
},
36+
Calc {
37+
#[arg(short = 'p', long = "prompt", default_value = "What is 6 times 7?")]
38+
prompt: String,
39+
#[arg(
40+
short = 'm',
41+
long = "model",
42+
default_value = "accounts/fireworks/models/minimax-m2p1"
43+
)]
44+
model: String,
45+
#[arg(short = 't', long = "temperature", default_value_t = 0.0)]
46+
temperature: f64,
47+
},
3248
}

src/commands/calc.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use std::error::Error;
2+
3+
use turingflow::rchain::chat_models::{ChatFireworks, ChatMessage};
4+
use turingflow::rchain::tools::{ToolDefinition, ToolFunction, ToolParam, ToolParamType};
5+
6+
fn multiply(a: i64, b: i64) -> i64 {
7+
a * b
8+
}
9+
10+
pub fn run_calc(
11+
prompt: impl Into<String>,
12+
model: impl Into<String>,
13+
temperature: f64,
14+
) -> Result<(), Box<dyn Error>> {
15+
let tool = ToolDefinition::from_function(
16+
ToolFunction::new("multiply", "Multiply two integers.")
17+
.with_param(ToolParam::new(
18+
"a",
19+
ToolParamType::Integer,
20+
true,
21+
Some("First factor.".to_string()),
22+
))
23+
.with_param(ToolParam::new(
24+
"b",
25+
ToolParamType::Integer,
26+
true,
27+
Some("Second factor.".to_string()),
28+
)),
29+
);
30+
31+
let llm = ChatFireworks::new(model, temperature)?.bind_tools(vec![tool]);
32+
let user_message = ChatMessage::user_text(prompt.into());
33+
let response = llm.invoke_messages(&[user_message.clone()])?;
34+
35+
if response.tool_calls.is_empty() {
36+
println!("Model answer: {}", response.content);
37+
return Ok(());
38+
}
39+
40+
for tool_call in &response.tool_calls {
41+
if tool_call.name != "multiply" {
42+
continue;
43+
}
44+
let a = tool_call
45+
.args
46+
.get("a")
47+
.and_then(|value| value.as_i64())
48+
.ok_or("Missing integer argument 'a' for multiply")?;
49+
let b = tool_call
50+
.args
51+
.get("b")
52+
.and_then(|value| value.as_i64())
53+
.ok_or("Missing integer argument 'b' for multiply")?;
54+
let result = multiply(a, b);
55+
56+
println!("Tool result: {}", result);
57+
58+
let final_response = llm.invoke_messages(&[
59+
user_message.clone(),
60+
ChatMessage::assistant_from_ai(&response),
61+
ChatMessage::tool_result(tool_call.id.clone(), result.to_string()),
62+
])?;
63+
64+
println!("Final answer: {}", final_response.content);
65+
}
66+
67+
Ok(())
68+
}

src/commands/image.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ pub fn run_image(
4141
]);
4242

4343
let response = llm.invoke(&[message])?;
44-
let parsed: serde_json::Value = serde_json::from_str(&response.content)
45-
.map_err(|_| "LLM response is not valid JSON")?;
44+
let parsed: serde_json::Value =
45+
serde_json::from_str(&response.content).map_err(|_| "LLM response is not valid JSON")?;
4646
let pretty = serde_json::to_string_pretty(&parsed)?;
4747
println!("{}", pretty);
4848

src/commands/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
pub mod image;
1+
pub mod calc;
22
pub mod embeddings;
3+
pub mod image;

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
pub mod pulse;
12
pub mod rchain;
23
pub mod tfpv1;

src/main.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ fn main() -> Result<(), Box<dyn Error>> {
2424
Commands::Embeddings { text_path, model } => {
2525
commands::embeddings::run_embeddings(text_path, model)?;
2626
}
27+
Commands::Calc {
28+
prompt,
29+
model,
30+
temperature,
31+
} => {
32+
commands::calc::run_calc(prompt, model, temperature)?;
33+
}
2734
}
2835

2936
Ok(())

src/pulse/app.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use std::error::Error;
2+
use std::path::Path;
3+
4+
use crate::pulse::theme::Theme;
5+
use crate::pulse::widget::WidgetNode;
6+
7+
#[derive(Debug, Clone)]
8+
pub struct PulseApp {
9+
root: WidgetNode,
10+
theme: Theme,
11+
}
12+
13+
impl PulseApp {
14+
pub fn new(root: impl Into<WidgetNode>) -> Self {
15+
Self {
16+
root: root.into(),
17+
theme: Theme::default(),
18+
}
19+
}
20+
21+
pub fn with_theme(mut self, theme: Theme) -> Self {
22+
self.theme = theme;
23+
self
24+
}
25+
26+
pub fn with_theme_file(mut self, path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>> {
27+
self.theme = Theme::from_file(path)?;
28+
Ok(self)
29+
}
30+
31+
pub fn render_to_string(&self) -> String {
32+
let mut output = String::new();
33+
output.push_str(&format!(
34+
"theme(fg={}, bg={}, primary={})\n",
35+
self.theme.colors.foreground, self.theme.colors.background, self.theme.colors.primary
36+
));
37+
output.push_str(&self.root.render_lines(&self.theme).join("\n"));
38+
output
39+
}
40+
41+
pub fn run(&self) {
42+
println!("{}", self.render_to_string());
43+
}
44+
}

0 commit comments

Comments
 (0)