Skip to content

Commit

Permalink
added model code
Browse files Browse the repository at this point in the history
  • Loading branch information
VarunJoshi10 committed Feb 28, 2024
1 parent 976265e commit b12ebe3
Show file tree
Hide file tree
Showing 9 changed files with 421 additions and 56 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "autosurf-ai-browser-extension",
"version": "1.1.0",
"description": "Web agent to do your bidding online",

"scripts": {
"build": "node utils/build.js",
"start": "node utils/webserver.js",
Expand All @@ -13,6 +12,8 @@
"dependencies": {
"@chakra-ui/icons": "^2.0.16",
"@chakra-ui/react": "^2.4.8",
"@cubist-labs/cubesigner-sdk": "^0.3.25",
"@cubist-labs/cubesigner-sdk-fs-storage": "^0.3.25",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@mozilla/readability": "^0.4.2",
Expand All @@ -21,6 +22,7 @@
"babel-jest": "^29.5.0",
"dotenv-webpack": "^8.0.1",
"eslint-plugin-unused-imports": "^2.0.0",
"express-handlebars": "^7.1.2",
"framer-motion": "^8.4.3",
"immer": "^9.0.21",
"lodash": "^4.17.21",
Expand Down
61 changes: 41 additions & 20 deletions src/common/App.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,60 @@
import React, { useState } from 'react';
import { Box, ChakraProvider, Heading, HStack } from '@chakra-ui/react';
import React from 'react';
import { useAppState } from '../state/store';
import ModelDropdown from './ModelDropdown';
import SetAPIKey from './SetAPIKey';
import TaskUI from './TaskUI';
import OptionsDropdown from './OptionsDropdown';
import logo from '../assets/img/icon-128.png';
import FormComponent from '../pages/Popup/FormComponent'; // Import the FormComponent

const App = () => {
const App: React.FC = () => {
const openAIKey = useAppState((state) => state.settings.openAIKey);
const [formSubmitted, setFormSubmitted] = useState(false);

const handleFormSubmit = () => {
setFormSubmitted(true);
};

return (
<ChakraProvider>
<Box p="8" fontSize="lg" w="full">
<HStack mb={4} alignItems="center">
<img
src={logo}
width={32}
height={32}
className="App-logo"
alt="logo"
/>

<Heading as="h1" size="lg" flex={1}>
Autosurf
</Heading>
<HStack spacing={2}>
<ModelDropdown />
<OptionsDropdown />
</HStack>
</HStack>
{openAIKey ? <TaskUI /> : <SetAPIKey />}
{/* {formSubmitted ? (
<AppUI />
) : (
<FormComponent onFormSubmit={handleFormSubmit} />
)} */}
<AppUI/>
</Box>
</ChakraProvider>
);
};

const AppUI: React.FC = () => {
const openAIKey = useAppState((state) => state.settings.openAIKey);

return (
<>
<HStack mb={4} alignItems="center">
<img
src={logo}
width={32}
height={32}
className="App-logo"
alt="logo"
/>

<Heading as="h1" size="lg" flex={1}>
Autosurf
</Heading>
<HStack spacing={2}>
<ModelDropdown />
<OptionsDropdown />
</HStack>
</HStack>
{openAIKey ? <TaskUI /> : <SetAPIKey />}
</>
);
};

export default App;
51 changes: 20 additions & 31 deletions src/helpers/determineNextAction.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
import {
Configuration,
CreateCompletionResponseUsage,
OpenAIApi,
} from 'openai';
import { useAppState } from '../state/store';
import { availableActions } from './availableActions';
import { ParsedResponseSuccess } from './parseResponse';
Expand Down Expand Up @@ -42,17 +37,8 @@ export async function determineNextAction(
) {
const model = useAppState.getState().settings.selectedModel;
const prompt = formatPrompt(taskInstructions, previousActions, simplifiedDOM);
const key = useAppState.getState().settings.openAIKey;
if (!key) {
notifyError?.('No OpenAI key found');
return null;
}

const openai = new OpenAIApi(
new Configuration({
apiKey: key,
})
);
const apiEndpoint = 'https://leo.tektorch.info/chat/completions'; // Replace with your own API endpoint

const maxSystemMessageLength = 3000; // Choose a reasonable length for the system message
const truncatedSystemMessage = systemMessage.substring(0, maxSystemMessageLength);
Expand All @@ -61,30 +47,33 @@ export async function determineNextAction(
try {
const messages = [
{
role: 'system',
content: truncatedSystemMessage,
role: "user",
content: prompt+" "+truncatedSystemMessage
}
]
console.log(JSON.stringify({ messages }))

const response = await fetch(apiEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
{ role: 'user', content: prompt },
];
body: JSON.stringify({ messages }),
}
);

const completion = await openai.createChatCompletion({
model: model,
messages: messages,
max_tokens: 500,
temperature: 0,
stop: ['</Action>'],
});
const data = await response.json();
console.log(data[0].content);

return {
usage: completion.data.usage as CreateCompletionResponseUsage,
usage: data.usage, // Replace with your own API response format
prompt,
response:
completion.data.choices[0].message?.content?.trim() + '</Action>',
response: data[0].content, // Replace with your own API response format
};
} catch (error: any) {
console.log('determineNextAction error', error);
if (error.response.data.error.message.includes('server error')) {
// Problem with the OpenAI API, try again
// Problem with the API, try again
if (notifyError) {
notifyError(error.response.data.error.message);
}
Expand Down Expand Up @@ -131,4 +120,4 @@ Current time: ${new Date().toLocaleString()}
Current page contents:
${pageContents}`;
}
}
8 changes: 8 additions & 0 deletions src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
"debugger",
"management"
],
"host_permissions": [
"https://accounts.google.com/",
"https://apis.google.com",
"https://www.gstatic.com",
"https://www.googleapis.com",
"https://securetoken.googleapis.com"
],

"action": {
"default_popup": "popup.html",
"default_icon": "icon-34.png"
Expand Down
41 changes: 41 additions & 0 deletions src/pages/Popup/FormComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { useEffect } from 'react';

interface FormComponentProps {
onFormSubmit: () => void;
}

const FormComponent: React.FC<FormComponentProps> = ({ onFormSubmit }) => {
useEffect(() => {
const handleSignInCompletion = (event: MessageEvent) => {
// Check if the message indicates sign-in completion
if (event.data === 'signInCompleted') {
// If sign-in completed, trigger the parent's callback
onFormSubmit();
}
};

// Add event listener to listen for messages from the child window
window.addEventListener('message', handleSignInCompletion);

// Load the specified URL in the child window
const childWindow = window.open('https://cubesigner-backend-production.up.railway.app/', '_blank');

return () => {
// Cleanup: remove event listener when the component unmounts
window.removeEventListener('message', handleSignInCompletion);

// Close the child window if it exists
if (childWindow) {
childWindow.close();
}
};
}, [onFormSubmit]);

return (
<form>
{/* This form will be hidden */}
</form>
);
};

export default FormComponent;
113 changes: 113 additions & 0 deletions src/pages/Popup/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import * as cs from "@cubist-labs/cubesigner-sdk";
import * as csFs from "@cubist-labs/cubesigner-sdk-fs-storage";
import * as dotenv from "dotenv";
import bodyParser from "body-parser";
import express from "express";
import { engine } from "express-handlebars";
import assert from "assert";

dotenv.config();

const PORT = process.env["PORT"] ?? 3000;
const GOOGLE_CLIENT_ID = process.env["GOOGLE_CLIENT_ID"];
const TWITTER_CLIENT_ID = process.env["TWITTER_CLIENT_ID"];
const FACEBOOK_CLIENT_ID = process.env["FACEBOOK_CLIENT_ID"];
const ORG_ID = process.env["ORG_ID"]!;
const API_ROOT = process.env["CS_API_ROOT"] ?? "https://gamma.signer.cubist.dev";
const TWITTER_COOKIE_NAME = "twitterCookie";

const app = express();

app.engine("handlebars", engine());
app.set("view engine", "handlebars");
app.set("views", "./views");

app.use(express.static("public"));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.json());

// Render landing page
app.get("/", (_, res) => {
res.render("index", {
googleClientId: GOOGLE_CLIENT_ID,
twitterClientId: TWITTER_CLIENT_ID,
twitterCookieName: TWITTER_COOKIE_NAME,
facebookClientId: FACEBOOK_CLIENT_ID,
orgId: ORG_ID,
apiRoot: API_ROOT,
port: PORT,
});
});

app.use((req, res, next) => {
res.setHeader('Content-Security-Policy', "script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' http://localhost:* http://127.0.0.1:* https://accounts.google.com;");
next();
});


app.get("/oauthCallback", (_, res) => {
res.render("oauthCallback")
});

app.post("/createUser", async (req, res) => {
try {
// In practice we would require the OIDC token and validate it.
// For this demo we just trust the client.
const id = req.body;
console.log(`Creating user ${id.email} with iss=${id.iss} and sub=${id.sub}`);
await createUser(id);
res.contentType("application/json").status(200).send();
} catch (e) {
console.error(`Failed to create user: ${e}`);
res.contentType("application/json").status(500).send();
}
});

app.listen(PORT);
console.log(`Listening on http://localhost:${PORT}`);

/**
* Create a user with the given OIDC claims.
* @param {cs.IdentityProof} proof The proof of identity
*/
async function createUser(proof: cs.IdentityProof) {
// Create a management session
console.log("Loading CubeSigner management session");
console.log(`Using org ${ORG_ID}`);

const cubesigner = await csFs.loadManagementSession();
const org = new cs.Org(cubesigner);

console.log("Verifying identity", proof);
try {
await org.verifyIdentity(proof);
console.log("Verified");
} catch (e) {
console.log(`Not verified: ${e}`);
throw e;
}

assert(proof.identity, "Identity should be set when proof is obtained using OIDC token");
const iss = proof.identity!.iss;
const sub = proof.identity!.sub;
const email = proof.email;
const name = proof.preferred_username;

// If user does not exist, create it
if (!proof.user_info?.user_id) {
console.log(`Creating OIDC user ${email}`);
const userId = await org.createOidcUser({ iss, sub }, email, {
name,
mfaPolicy: {
num_auth_factors: 1,
allowed_mfa_types: ["Fido"],
},
});
console.log(`Creating key for user ${userId}...`);
// Create a key for the OIDC user
const key = await org.createKey(cs.Secp256k1.Evm, userId);
console.log(`${await key.type()} key created ${key.materialId}`);
} else {
console.log(`User ${proof.user_info.user_id} already exists for ${email}`);
}
}
Empty file.
11 changes: 11 additions & 0 deletions src/pages/Popup/views/oauthCallback.handlebars
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script>
let params = new URLSearchParams(window.location.search);
let state = params.get("state");
let code = params.get("code");
if (state && params) {
new BroadcastChannel("oauth_code").postMessage({
code, state
})
}
window.close();
</script>
Loading

0 comments on commit b12ebe3

Please sign in to comment.