Skip to content

Commit 34fedd0

Browse files
authored
Merge pull request #70 from neatwork-ai/rename-extension
Renamed DisplayName
2 parents df74da2 + 5166dff commit 34fedd0

File tree

11 files changed

+205
-6
lines changed

11 files changed

+205
-6
lines changed

crates/neatcoder/src/consts.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ pub const CONFIG_FILES: [&str; 9] = [
1515
"Package.swift", // Swift
1616
".gitignore",
1717
];
18+
19+
pub const BASE_BETA_URL: &str = "https://api.openai.com/v1/beta";
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
use anyhow::{anyhow, Result};
2+
use reqwest::{header::HeaderMap, Client};
3+
use serde::{
4+
de::{self, Visitor},
5+
Deserialize, Deserializer, Serialize,
6+
};
7+
use serde_json::json;
8+
use std::{collections::HashMap, fmt};
9+
10+
use crate::{consts::BASE_BETA_URL, openai::params::OpenAIModels};
11+
12+
#[derive(Serialize, Debug)]
13+
pub struct AssistantRequest {
14+
pub name: String,
15+
pub instructions: String,
16+
pub tools: Vec<String>, // TODO: "tools": [{"type": "code_interpreter"}]
17+
pub model: OpenAIModels,
18+
}
19+
20+
#[derive(Debug, Serialize, Deserialize)]
21+
pub struct Assistant {
22+
id: String,
23+
object: String,
24+
created_at: u32, // TODO: Should be a timestamp
25+
name: String,
26+
description: Option<String>,
27+
model: OpenAIModels,
28+
instructions: Option<String>,
29+
tools: Vec<Tool>,
30+
file_ids: Vec<String>,
31+
metadata: HashMap<String, String>,
32+
}
33+
34+
#[derive(Debug, Serialize)]
35+
pub enum Tool {
36+
CodeInterpreter,
37+
Retrieval,
38+
FunctionCall,
39+
}
40+
41+
impl Tool {
42+
pub fn new(tool: String) -> Self {
43+
let tool = match tool.as_str() {
44+
"code_interpreter" => Tool::CodeInterpreter,
45+
"retrieval" => Tool::Retrieval,
46+
"function" => Tool::FunctionCall,
47+
_ => panic!("Invalid tool {}", tool),
48+
};
49+
50+
tool
51+
}
52+
53+
pub fn as_string(&self) -> String {
54+
match self {
55+
Tool::CodeInterpreter => String::from("code_interpreter"),
56+
Tool::Retrieval => String::from("retrieval"),
57+
Tool::FunctionCall => String::from("function"),
58+
}
59+
}
60+
}
61+
62+
impl<'de> Deserialize<'de> for Tool {
63+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64+
where
65+
D: Deserializer<'de>,
66+
{
67+
struct ToolVisitor;
68+
69+
impl<'de> Visitor<'de> for ToolVisitor {
70+
type Value = Tool;
71+
72+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
73+
formatter.write_str("a string representing an OpenAI model")
74+
}
75+
76+
fn visit_str<E>(self, value: &str) -> Result<Tool, E>
77+
where
78+
E: de::Error,
79+
{
80+
match value {
81+
"code_interpreter" => Ok(Tool::CodeInterpreter),
82+
"retrieval" => Ok(Tool::Retrieval),
83+
"function" => Ok(Tool::FunctionCall),
84+
_ => Err(E::custom(format!(
85+
"unexpected OpenAI tool: {}",
86+
value
87+
))),
88+
}
89+
}
90+
}
91+
92+
deserializer.deserialize_str(ToolVisitor)
93+
}
94+
}
95+
96+
impl AssistantRequest {
97+
pub async fn create_assistant(
98+
self,
99+
client: &Client,
100+
headers: &HeaderMap,
101+
) -> Result<Assistant> {
102+
let response = client
103+
.post(&format!("{}/assistants", BASE_BETA_URL))
104+
.headers(headers.clone())
105+
.json(&json!({
106+
"name": self.name, // "Math Tutor",
107+
"instructions": self.instructions, // "You are a personal math tutor. Write and run code to answer math questions.",
108+
"tools": self.tools, // [{"type": "code_interpreter"}],
109+
"model": self.model, // "gpt-4-1106-preview"
110+
}))
111+
.send()
112+
.await?;
113+
114+
if response.status().is_success() {
115+
let assistant = response.json::<Assistant>().await?;
116+
println!("Create Assistant response: {:?}", assistant);
117+
Ok(assistant)
118+
} else {
119+
// If not successful, perhaps you want to parse it differently or handle the error
120+
Err(anyhow!(response.status()))
121+
}
122+
}
123+
}

crates/neatcoder/src/openai/assistant/message.rs

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod assistant;

crates/neatcoder/src/openai/assistant/thread.rs

Whitespace-only changes.

crates/neatcoder/src/openai/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod assistant;
12
///< Client for interacting with the OpenAI API.
23
pub mod msg;
34
pub mod params;

crates/neatcoder/src/openai/params.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use anyhow::Result;
2-
use serde::Serialize;
3-
use std::collections::HashMap;
2+
use serde::{
3+
de::{self, Visitor},
4+
Deserialize, Deserializer, Serialize,
5+
};
6+
use std::{collections::HashMap, fmt};
47
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
58

69
use crate::{
@@ -245,6 +248,43 @@ impl OpenAIModels {
245248
}
246249
}
247250

251+
impl<'de> Deserialize<'de> for OpenAIModels {
252+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
253+
where
254+
D: Deserializer<'de>,
255+
{
256+
struct OpenAIModelsVisitor;
257+
258+
impl<'de> Visitor<'de> for OpenAIModelsVisitor {
259+
type Value = OpenAIModels;
260+
261+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
262+
formatter.write_str("a string representing an OpenAI model")
263+
}
264+
265+
fn visit_str<E>(self, value: &str) -> Result<OpenAIModels, E>
266+
where
267+
E: de::Error,
268+
{
269+
match value {
270+
"gpt-4-32k" => Ok(OpenAIModels::Gpt432k),
271+
"gpt-4" => Ok(OpenAIModels::Gpt4),
272+
"gpt-3.5-turbo" => Ok(OpenAIModels::Gpt35Turbo),
273+
"gpt-3.5-turbo-16k" => Ok(OpenAIModels::Gpt35Turbo16k),
274+
"gpt-3.5-turbo-1106" => Ok(OpenAIModels::Gpt35Turbo1106),
275+
"gpt-4-1106-preview" => Ok(OpenAIModels::Gpt41106Preview),
276+
_ => Err(E::custom(format!(
277+
"unexpected OpenAI model: {}",
278+
value
279+
))),
280+
}
281+
}
282+
}
283+
284+
deserializer.deserialize_str(OpenAIModelsVisitor)
285+
}
286+
}
287+
248288
impl Default for OpenAIParams {
249289
fn default() -> Self {
250290
Self {

vsce/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes to the "neatcoder" extension will be documented in this file
44

55
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
66

7+
## [0.2.4] - 08/11/2023
8+
9+
### Changed
10+
- Reinstated classic Open AI models `gpt-3.5` and `gpt-4` models
11+
12+
### Fixed
13+
- Chat http request error handling
14+
715
## [0.2.3] - 07/11/2023
816

917
### Added

vsce/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"name": "neatcoder",
3-
"displayName": "Neatwork AI - GPT4 on Steroids",
3+
"displayName": "Neatwork AI - GPT4 Turbo on Steroids",
44
"description": "Turn your IDE into an AI Sofware engineer.",
5-
"version": "0.2.3",
5+
"version": "0.2.4",
66
"publisher": "NeatworkAi",
77
"repository": {
88
"url": "https://github.com/neatwork-ai/neatcoder-issues.git",

vsce/src/chat/handlers.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import * as vscode from "vscode";
2+
import { window } from "vscode";
23
import { getOrSetApiKey } from "../utils";
34
import * as wasm from "../../pkg/neatcoder";
45
import * as https from "https";
6+
import * as http from "http";
57
import * as url from "url";
68
import { MessageBuffer } from "../utils/httpClient";
79
import { getLLMParams } from "../utils/utils";
@@ -55,6 +57,22 @@ export async function promptLLM(
5557

5658
const req = https.request(options, async (res) => {
5759
console.log(`STATUS: ${res.statusCode}`);
60+
if (res.statusCode !== 202) {
61+
const statusMessage =
62+
http.STATUS_CODES[res.statusCode!] || "Unknown status code";
63+
64+
console.log(`STATUS: ${res.statusCode} ${statusMessage}`);
65+
// Here the use of `window` and `webviewPanel` assumes this is within a VS Code extension
66+
window.showErrorMessage(
67+
`HTTP error: STATUS: ${res.statusCode} ${statusMessage}`
68+
);
69+
70+
reject(
71+
new Error(`HTTP error: STATUS: ${res.statusCode} ${statusMessage}`)
72+
);
73+
return; // Stop further processing
74+
}
75+
5876
res.setEncoding("utf8");
5977
res.pause();
6078

vsce/src/utils/utils.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,12 @@ export async function getOrSetModelVersion(): Promise<wasm.OpenAIModels | null>
280280

281281
if (!modelVersion) {
282282
const value = await vscode.window.showQuickPick(
283-
["gpt-3.5-turbo-1106", "gpt-4-1106-preview"],
283+
[
284+
"gpt-3.5-turbo-1106",
285+
"gpt-4-1106-preview",
286+
"gpt-3.5-turbo-16k",
287+
"gpt-4",
288+
],
284289
{
285290
canPickMany: false,
286291
placeHolder: "Select an OpenAI model", // This is the placeholder text
@@ -306,11 +311,12 @@ export async function getOrSetModelVersion(): Promise<wasm.OpenAIModels | null>
306311
return fromModelVersionToEnum(modelVersion);
307312
}
308313

314+
// TODO: Remove dulplicated logic...
309315
export async function setModelVersion() {
310316
let config = vscode.workspace.getConfiguration("extension");
311317

312318
const value = await vscode.window.showQuickPick(
313-
["gpt-3.5-turbo-1106", "gpt-4-1106-preview"],
319+
["gpt-3.5-turbo-1106", "gpt-4-1106-preview", "gpt-3.5-turbo-16k", "gpt-4"],
314320
{
315321
canPickMany: false,
316322
placeHolder: "Select an OpenAI model", // This is the placeholder text

0 commit comments

Comments
 (0)