Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add eslint and prettier config. Add pr check for lint #156

Merged
merged 1 commit into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules/
dist/
build/
electron-dist/
.next
tailwind.config.js
.dockerigore
24 changes: 23 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
{
"extends": "next/core-web-vitals"
"extends": [
"next/core-web-vitals",
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended"
],
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"plugins": [
"prettier",
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/ban-ts-comment": "off",
"prettier/prettier": ["error", { "endOfLine": "auto" }],
"react/react-in-jsx-scope": "off",
"react/prop-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_"}]
}
}
25 changes: 25 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Lint

on:
pull_request:
branches:
- main

jobs:
lint:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '21'

- name: Install dependencies
run: npm install

- name: Run linter
run: npm run lint
7 changes: 7 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules/
dist/
build/
electron-dist/
.next
tailwind.config.js
.dockerigore
13 changes: 13 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"jsxBracketSameLine": false,
"arrowParens": "always",
"endOfLine": "lf",
"parser": "typescript"
}
118 changes: 69 additions & 49 deletions actions/auth/auth.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
"use server"

import {cookies} from "next/headers"
import {create, get, list } from "@/actions/common"
import { gpt } from "@/config/env"
import { Block, RunEventType, ToolDef } from "@gptscript-ai/gptscript"
'use server';

import { cookies } from 'next/headers';
import { create, get, list } from '@/actions/common';
import { gpt } from '@/config/env';
import { RunEventType, ToolDef } from '@gptscript-ai/gptscript';

const tokenRequestToolInstructions = `
Credential: github.com/gptscript-ai/gateway-creds as github.com/gptscript-ai/gateway
Expand All @@ -29,34 +28,45 @@ print(json.dumps(output), end="")
`;

export interface AuthProvider {
id?: string
type: string
serviceName?: string
slug?: string
clientID?: string
clientSecret?: string
oauthURL?: string
tokenURL?: string
scopes?: string
redirectURL?: string
disabled?: boolean
id?: string;
type: string;
serviceName?: string;
slug?: string;
clientID?: string;
clientSecret?: string;
oauthURL?: string;
tokenURL?: string;
scopes?: string;
redirectURL?: string;
disabled?: boolean;
}

export async function setCookies(token: string, expiresAt: string): Promise<void> {
cookies().set("gateway_token", token, {domain: "localhost"})
cookies().set("expires_at", expiresAt, {domain: "localhost"})
export async function setCookies(
token: string,
expiresAt: string
): Promise<void> {
cookies().set('gateway_token', token, { domain: 'localhost' });
cookies().set('expires_at', expiresAt, { domain: 'localhost' });
}

export async function logout(): Promise<void> {
cookies().delete("gateway_token")
cookies().delete('gateway_token');
}

export async function getAuthProviders(): Promise<AuthProvider[]> {
return await list("auth-providers")
return await list('auth-providers');
}

export async function createTokenRequest(id: string, oauthServiceName: string): Promise<string> {
return (await create({id: id, serviceName: oauthServiceName} as any, "token-request"))["token-path"]
export async function createTokenRequest(
id: string,
oauthServiceName: string
): Promise<string> {
return (
await create(
{ id: id, serviceName: oauthServiceName } as any,
'token-request'
)
)['token-path'];
}

/*
Expand All @@ -69,32 +79,42 @@ export async function createTokenRequest(id: string, oauthServiceName: string):
*/
let loginTimeout: NodeJS.Timeout | null = null;
export async function loginThroughTool(): Promise<void> {
if (loginTimeout) {
clearTimeout(loginTimeout);
loginTimeout = null;
}

const run = await gpt().evaluate({instructions: tokenRequestToolInstructions} as ToolDef, {prompt: true})
run.on(RunEventType.Prompt, (data) => {
gpt().promptResponse({id: data.id, responses: {}})
})

const response = JSON.parse(await run.text()) as {token: string, expiresAt: string}
setCookies(response.token, response.expiresAt);

loginTimeout = setTimeout(() => {
loginTimeout = null;
loginThroughTool();
}, new Date(response.expiresAt).getTime() - Date.now() - 1000 * 60 * 5)
if (loginTimeout) {
clearTimeout(loginTimeout);
loginTimeout = null;
}

const run = await gpt().evaluate(
{ instructions: tokenRequestToolInstructions } as ToolDef,
{ prompt: true }
);
run.on(RunEventType.Prompt, (data) => {
gpt().promptResponse({ id: data.id, responses: {} });
});

const response = JSON.parse(await run.text()) as {
token: string;
expiresAt: string;
};
setCookies(response.token, response.expiresAt);

loginTimeout = setTimeout(
() => {
loginTimeout = null;
loginThroughTool();
},
new Date(response.expiresAt).getTime() - Date.now() - 1000 * 60 * 5
);
}

export async function pollForToken(id: string): Promise<string> {
while (true) {
const token = (await get<any>("token-request", id)).token || ""
if (token != "") {
return token
}

await new Promise(r => setTimeout(r, 1000))
// eslint-disable-next-line no-constant-condition
while (true) {
const token = (await get<any>('token-request', id)).token || '';
if (token != '') {
return token;
}
}

await new Promise((r) => setTimeout(r, 1000));
}
}
58 changes: 31 additions & 27 deletions actions/common.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,49 @@
"use server"
'use server';

import {cookies} from "next/headers"
import { GATEWAY_URL } from "@/config/env"
import { cookies } from 'next/headers';
import { GATEWAY_URL } from '@/config/env';

export async function list<T>(path: string): Promise<T> {
return request(undefined, path, "GET")
return request(undefined, path, 'GET');
}

export async function get<T>(path: string, id: string): Promise<T> {
if (id !== "") {
path = `${path}/${id}`
}
return request(undefined, path, "GET")
if (id !== '') {
path = `${path}/${id}`;
}
return request(undefined, path, 'GET');
}

export async function update<T>(obj: T, path: string): Promise<T> {
return request(obj, path, "PATCH")
return request(obj, path, 'PATCH');
}

export async function create<T>(obj: T, path: string): Promise<T> {
return request(obj, path, "POST")
return request(obj, path, 'POST');
}

export async function del<T>(id: string, path: string): Promise<any> {
return request(undefined, `${path}/${id}`, "DELETE")
return request(undefined, `${path}/${id}`, 'DELETE');
}

export async function request<T>(obj: T, path: string, method: string): Promise<any> {
const resp = await fetch(`${GATEWAY_URL()}/api/${path}`, {
method: method,
headers: {
"Content-type": "application/json",
Authorization: `Bearer ${(cookies().get("gateway_token") || {}).value || ""}`
},
body: obj ? JSON.stringify(obj) : undefined
})

const res = await resp.json()
if (resp.status < 200 || resp.status >= 400) {
throw Error(`Unexpected status ${resp.status}: ${res.error}`)
}

return res
export async function request<T>(
obj: T,
path: string,
method: string
): Promise<any> {
const resp = await fetch(`${GATEWAY_URL()}/api/${path}`, {
method: method,
headers: {
'Content-type': 'application/json',
Authorization: `Bearer ${(cookies().get('gateway_token') || {}).value || ''}`,
},
body: obj ? JSON.stringify(obj) : undefined,
});

const res = await resp.json();
if (resp.status < 200 || resp.status >= 400) {
throw Error(`Unexpected status ${resp.status}: ${res.error}`);
}

return res;
}
4 changes: 2 additions & 2 deletions actions/gateway.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"use server"
'use server';

import { GATEWAY_URL } from '@/config/env';

export const getGatewayUrl = async () => GATEWAY_URL();
export const getGatewayUrl = async () => GATEWAY_URL();
34 changes: 18 additions & 16 deletions actions/gptscript.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
"use server"
'use server';

import { Tool, Block, Text } from '@gptscript-ai/gptscript';
import { gpt } from '@/config/env';

export const rootTool = async (toolContent: string): Promise<Tool> => {
if (!toolContent) return {} as Tool;
const parsedTool = await gpt().parseTool(toolContent);
for (let block of parsedTool) {
if (block.type === 'tool') return block;
}
return {} as Tool;
}
if (!toolContent) return {} as Tool;
const parsedTool = await gpt().parseTool(toolContent);
for (const block of parsedTool) {
if (block.type === 'tool') return block;
}
return {} as Tool;
};

export const parse = async (toolContent: string): Promise<Tool[]> => {
const parsedTool = await gpt().parseTool(toolContent);
return parsedTool.filter((block) => block.type === 'tool' && !block.name?.startsWith("metadata")) as Tool[];
}
const parsedTool = await gpt().parseTool(toolContent);
return parsedTool.filter(
(block) => block.type === 'tool' && !block.name?.startsWith('metadata')
) as Tool[];
};

export const getTexts = async (toolContent: string): Promise<Text[]> => {
const parsedTool = await gpt().parseTool(toolContent);
return parsedTool.filter((block) => block.type === 'text') as Text[];
}
const parsedTool = await gpt().parseTool(toolContent);
return parsedTool.filter((block) => block.type === 'text') as Text[];
};

export const stringify = async (script: Block[]): Promise<string> => {
return await gpt().stringify(script);
}
return await gpt().stringify(script);
};
8 changes: 4 additions & 4 deletions actions/me/me.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { get } from "@/actions/common"
import { get } from '@/actions/common';

export interface Me {
username: string
email: string
username: string;
email: string;
}

export async function getMe(): Promise<Me> {
return await get("me", "")
return await get('me', '');
}
Loading
Loading