Skip to content

Commit e723498

Browse files
committed
create node.js pkg
1 parent ffeca05 commit e723498

File tree

4 files changed

+54
-37
lines changed

4 files changed

+54
-37
lines changed

lib/index.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const genai = require('../index.node');
2+
3+
class GeminiFlash {
4+
constructor(api_key) {
5+
this.api_key = api_key;
6+
}
7+
8+
async generate_content(prompt) {
9+
try {
10+
const response = await genai.generate_content(this.api_key, prompt);
11+
return response;
12+
} catch (error) {
13+
console.error("Error generating content:", error);
14+
throw error;
15+
}
16+
}
17+
}
18+
19+
module.exports = GeminiFlash;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "gemini_flash",
33
"version": "0.1.0",
44
"description": "Client for Google's Gemini-1.5-Flash Generative AI Model",
5-
"main": "index.node",
5+
"main": "lib/index.js",
66
"scripts": {
77
"test": "cargo test",
88
"cargo-build": "cargo build --message-format=json > cargo.log",

src/lib.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
use curl::easy::{Easy, List};
22
use neon::prelude::*;
3+
use pulldown_cmark::{Event, Options, Parser, Tag, TagEnd};
34
use serde_json::to_string;
4-
use pulldown_cmark::{Event, Parser, Tag, TagEnd, Options};
55

66
mod request;
77
mod response;
88
use request::*;
9-
// use response::Response;
109

1110
#[neon::main]
1211
fn main(mut cx: ModuleContext) -> NeonResult<()> {
1312
cx.export_function("generate_content", generate_content)?;
14-
cx.export_function("markdown_to_text", markdown_to_text)?;
1513
Ok(())
1614
}
1715

18-
// @args api_key: String, prompt: &str
19-
pub fn generate_content(mut cx: FunctionContext) -> JsResult<JsString> {
16+
pub fn generate_content(mut cx: FunctionContext) -> JsResult<JsObject> {
2017
let api_key = cx.argument::<JsString>(0)?.value(&mut cx);
2118
let prompt = cx.argument::<JsString>(1)?.value(&mut cx);
2219

@@ -56,13 +53,13 @@ pub fn generate_content(mut cx: FunctionContext) -> JsResult<JsString> {
5653
}
5754

5855
let json_data = String::from_utf8(response_data).unwrap();
59-
// let response: Response = serde_json::from_str(json_data.as_str()).unwrap();
60-
// response
61-
Ok(cx.string(json_data))
56+
let response: response::Response = serde_json::from_str(json_data.as_str()).unwrap();
57+
let js_res_obj = to_jsobj(cx, response);
58+
59+
Ok(js_res_obj.unwrap())
6260
}
6361

64-
pub fn markdown_to_text(mut cx: FunctionContext) -> JsResult<JsString> {
65-
let markdown = cx.argument::<JsString>(0)?.value(&mut cx);
62+
pub fn markdown_to_text(markdown: &str) -> String {
6663
let options = Options::empty();
6764
let parser = Parser::new_ext(&markdown, options);
6865
let mut plain_text = String::new();
@@ -71,18 +68,40 @@ pub fn markdown_to_text(mut cx: FunctionContext) -> JsResult<JsString> {
7168
match event {
7269
Event::Text(text) | Event::Code(text) => plain_text.push_str(&text),
7370
Event::Start(tag) => match tag {
74-
Tag::Paragraph | Tag::Heading{..} => plain_text.push_str("\n\n"),
71+
Tag::Paragraph | Tag::Heading { .. } => plain_text.push_str("\n\n"),
7572
Tag::List(_) => plain_text.push('\n'),
7673
Tag::Item => plain_text.push_str("\n• "),
77-
_ => {},
74+
_ => {}
7875
},
7976
Event::End(tag) => match tag {
80-
TagEnd::Paragraph | TagEnd::Heading{..} => plain_text.push('\n'),
81-
_ => {},
77+
TagEnd::Paragraph | TagEnd::Heading { .. } => plain_text.push('\n'),
78+
_ => {}
8279
},
8380
_ => {}
8481
}
8582
}
8683

87-
Ok(cx.string(plain_text))
84+
plain_text
85+
}
86+
87+
fn to_jsobj(mut cx: FunctionContext, res: response::Response) -> JsResult<JsObject> {
88+
let obj = cx.empty_object();
89+
90+
let text = cx.string(markdown_to_text(&res.candidates[0].content.parts[0].text));
91+
obj.set(&mut cx, "text", text)?;
92+
93+
let finish_reason = cx.string(&res.candidates[0].finishReason);
94+
obj.set(&mut cx, "finish_reason", finish_reason)?;
95+
96+
let usage_metadata = cx.string(to_string(&res.usageMetadata).unwrap());
97+
obj.set(&mut cx, "usage_metadata", usage_metadata)?;
98+
99+
let role = cx.string(&res.candidates[0].content.role);
100+
obj.set(&mut cx, "role", role)?;
101+
102+
let prompt_feedback = to_string(&res.candidates[0].safetyRatings).unwrap();
103+
let prompt_feedback_str = cx.string(prompt_feedback);
104+
obj.set(&mut cx, "prompt_feedback", prompt_feedback_str)?;
105+
106+
Ok(obj)
88107
}

src/response.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ pub struct Candidate {
1414
pub finishReason: String,
1515
pub index: u32,
1616
pub safetyRatings: Vec<SafetyRating>,
17-
pub citationMetadata: CitationMetadata,
1817
}
1918

2019
#[allow(non_snake_case)]
@@ -37,12 +36,6 @@ pub struct SafetyRating {
3736
pub probability: String,
3837
}
3938

40-
#[allow(non_snake_case)]
41-
#[derive(Serialize, Deserialize, Debug)]
42-
pub struct CitationMetadata {
43-
pub citationSources: Vec<CitationSource>,
44-
}
45-
4639
#[allow(non_snake_case)]
4740
#[derive(Serialize, Deserialize, Debug)]
4841
pub struct CitationSource {
@@ -59,17 +52,3 @@ pub struct UsageMetadata {
5952
pub candidatesTokenCount: u32,
6053
pub totalTokenCount: u32,
6154
}
62-
63-
// impl Response {
64-
// pub fn text(&self) -> String {
65-
// utils::markdown_to_text(self.candidates[0].content.parts[0].text.as_str())
66-
// }
67-
68-
// pub fn prompt_feedback(&self) -> &Vec<SafetyRating> {
69-
// self.candidates[0].safetyRatings.as_ref()
70-
// }
71-
72-
// pub fn candidates(&self) -> &Vec<Candidate> {
73-
// self.candidates.as_ref()
74-
// }
75-
// }

0 commit comments

Comments
 (0)