Skip to content

Commit aa7909e

Browse files
committed
misc: small fix or general refactoring i did not bother commenting
1 parent 382333b commit aa7909e

File tree

2 files changed

+82
-64
lines changed

2 files changed

+82
-64
lines changed

nerve-core/src/agent/generator/openai.rs

+67-57
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,71 @@ impl OpenAIClient {
5454

5555
Ok(Self { model, client })
5656
}
57+
58+
async fn get_tools_if_supported(&self, state: &SharedState) -> Vec<FunctionTool> {
59+
let mut tools = vec![];
60+
61+
// if native tool calls are supported (and XML was not forced)
62+
if state.lock().await.native_tools_support {
63+
// for every namespace available to the model
64+
for group in state.lock().await.get_namespaces() {
65+
// for every action of the namespace
66+
for action in &group.actions {
67+
let mut required = vec![];
68+
let mut properties = HashMap::new();
69+
70+
if let Some(example) = action.example_payload() {
71+
required.push("payload".to_string());
72+
properties.insert(
73+
"payload".to_string(),
74+
OpenAiToolFunctionParameterProperty {
75+
the_type: "string".to_string(),
76+
description: format!(
77+
"The main function argument, use this as a template: {}",
78+
example
79+
),
80+
},
81+
);
82+
}
83+
84+
if let Some(attrs) = action.example_attributes() {
85+
for name in attrs.keys() {
86+
required.push(name.to_string());
87+
properties.insert(
88+
name.to_string(),
89+
OpenAiToolFunctionParameterProperty {
90+
the_type: "string".to_string(),
91+
description: name.to_string(),
92+
},
93+
);
94+
}
95+
}
96+
97+
let function = FunctionDefinition {
98+
name: action.name().to_string(),
99+
description: Some(action.description().to_string()),
100+
parameters: Some(serde_json::json!(OpenAiToolFunctionParameters {
101+
the_type: "object".to_string(),
102+
required,
103+
properties,
104+
})),
105+
};
106+
107+
tools.push(FunctionTool {
108+
the_type: "function".to_string(),
109+
function,
110+
});
111+
}
112+
}
113+
114+
log::trace!("openai.tools={:?}", &tools);
115+
116+
// let j = serde_json::to_string_pretty(&tools).unwrap();
117+
// log::info!("{j}");
118+
}
119+
120+
tools
121+
}
57122
}
58123

59124
#[async_trait]
@@ -74,7 +139,7 @@ impl Client for OpenAIClient {
74139
},
75140
openai_api_rust::Message {
76141
role: Role::User,
77-
content: Some("Call the test function.".to_string()),
142+
content: Some("Execute the test function.".to_string()),
78143
tool_calls: None,
79144
},
80145
];
@@ -154,62 +219,7 @@ impl Client for OpenAIClient {
154219
});
155220
}
156221

157-
let mut tools = vec![];
158-
if state.lock().await.native_tools_support {
159-
for group in state.lock().await.get_namespaces() {
160-
for action in &group.actions {
161-
let mut required = vec![];
162-
let mut properties = HashMap::new();
163-
164-
if let Some(example) = action.example_payload() {
165-
required.push("payload".to_string());
166-
properties.insert(
167-
"payload".to_string(),
168-
OpenAiToolFunctionParameterProperty {
169-
the_type: "string".to_string(),
170-
description: format!(
171-
"The main function argument, use this as a template: {}",
172-
example
173-
),
174-
},
175-
);
176-
}
177-
178-
if let Some(attrs) = action.example_attributes() {
179-
for name in attrs.keys() {
180-
required.push(name.to_string());
181-
properties.insert(
182-
name.to_string(),
183-
OpenAiToolFunctionParameterProperty {
184-
the_type: "string".to_string(),
185-
description: name.to_string(),
186-
},
187-
);
188-
}
189-
}
190-
191-
let function = FunctionDefinition {
192-
name: action.name().to_string(),
193-
description: Some(action.description().to_string()),
194-
parameters: Some(serde_json::json!(OpenAiToolFunctionParameters {
195-
the_type: "object".to_string(),
196-
required,
197-
properties,
198-
})),
199-
};
200-
201-
tools.push(FunctionTool {
202-
the_type: "function".to_string(),
203-
function,
204-
});
205-
}
206-
}
207-
208-
log::trace!("openai.tools={:?}", &tools);
209-
210-
// let j = serde_json::to_string_pretty(&tools).unwrap();
211-
// log::info!("{j}");
212-
}
222+
let tools = self.get_tools_if_supported(&state).await;
213223

214224
let body = ChatBody {
215225
model: self.model.to_string(),

nerve-core/src/agent/namespaces/filesystem/mod.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,21 @@ impl Action for AppendToFile {
202202
}
203203
};
204204

205-
// parse the payload as a JSON object
206-
let one_line_json = if let Ok(value) = serde_json::from_str::<serde_json::Value>(&payload) {
207-
// reconvert to make sure it's on a single line
208-
serde_json::to_string(&value).unwrap()
205+
// get lowercase file extension from filepath
206+
let extension = filepath.rsplit('.').next().unwrap_or("").to_lowercase();
207+
208+
let content_to_append = if extension == "json" || extension == "jsonl" {
209+
// parse the payload as a JSON object
210+
if let Ok(value) = serde_json::from_str::<serde_json::Value>(&payload) {
211+
// reconvert to make sure it's on a single line
212+
serde_json::to_string(&value).unwrap()
213+
} else {
214+
log::error!("can't parse payload as JSON: {}", payload);
215+
serde_json::to_string(&InvalidJSON { data: payload }).unwrap()
216+
}
209217
} else {
210-
log::error!("can't parse payload as JSON: {}", payload);
211-
serde_json::to_string(&InvalidJSON { data: payload }).unwrap()
218+
// add as it is
219+
payload
212220
};
213221

214222
// append the JSON to the file
@@ -217,7 +225,7 @@ impl Action for AppendToFile {
217225
.create(true)
218226
.open(&filepath)?;
219227

220-
writeln!(file, "{}", one_line_json)?;
228+
writeln!(file, "{}", content_to_append)?;
221229

222230
Ok(None)
223231
}

0 commit comments

Comments
 (0)