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

First stab at JS-based CLI for Fixie. #247

Merged
merged 11 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
File renamed without changes.
File renamed without changes.
File renamed without changes.
56 changes: 56 additions & 0 deletions packages/fixie-hello-world/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "fixie-hello-world",
"version": "1.0.0",
"devDependencies": {
"@tsconfig/node18": "^2.0.1",
"@types/lodash": "^4.14.195",
"@types/node": "^20.3.1",
"@types/prompt-sync": "^4.2.0",
"@types/uuid": "^9.0.2",
"@types/yargs": "^17.0.24",
"@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.60.0",
"eslint": "^8.40.0",
"eslint-config-nth": "^2.0.1",
"typescript": "^5.1.3"
},
"private": true,
"type": "module",
"scripts": {
"dev": "yarn build && npx ts-node dist/serve-bin.js --port 8080 --package-path fixie",
"lint": "eslint . --max-warnings 0",
"lint:fix": "eslint . --fix",
"typecheck": "tsc -p tsconfig.json",
"build": "yarn run typecheck",
"bin:dev": "npx ts-node dist/serve-bin.js --port 8080 --package-path fixie"
},
"dependencies": {
"@opentelemetry/api": "^1.4.1",
"@opentelemetry/api-logs": "^0.41.1",
"@opentelemetry/exporter-logs-otlp-grpc": "^0.41.1",
"@opentelemetry/exporter-trace-otlp-grpc": "^0.41.1",
"@opentelemetry/instrumentation-fastify": "^0.32.0",
"@opentelemetry/instrumentation-fetch": "^0.41.1",
"@opentelemetry/instrumentation-http": "^0.41.2",
"@opentelemetry/sdk-logs": "^0.41.1",
"@opentelemetry/sdk-node": "^0.41.1",
"ai-jsx": "*",
"dotenv": "^16.3.1",
"fastify": "^4.20.0",
"yargs": "^17.7.2"
},
"bin": {
"serve-bin": "dist/serve-bin.js"
},
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"default": "./dist/index.cjs"
}
}
}
}
File renamed without changes.
13 changes: 13 additions & 0 deletions packages/fixie-hello-world/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "@tsconfig/node18/tsconfig.json",
"include": ["src/**/*", ".eslintrc.cjs"],
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "ai-jsx",
"moduleResolution": "node16",
"module": "esnext",
"resolveJsonModule": true,
"outDir": "dist",
"declaration": true
}
}
84 changes: 30 additions & 54 deletions packages/fixie/package.json
Original file line number Diff line number Diff line change
@@ -1,56 +1,32 @@
{
"name": "fixie",
"version": "1.0.0",
"devDependencies": {
"@tsconfig/node18": "^2.0.1",
"@types/lodash": "^4.14.195",
"@types/node": "^20.3.1",
"@types/prompt-sync": "^4.2.0",
"@types/uuid": "^9.0.2",
"@types/yargs": "^17.0.24",
"@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.60.0",
"eslint": "^8.40.0",
"eslint-config-nth": "^2.0.1",
"typescript": "^5.1.3"
},
"private": true,
"type": "module",
"scripts": {
"dev": "yarn build && npx ts-node dist/serve-bin.js --port 8080 --package-path fixie",
"lint": "eslint . --max-warnings 0",
"lint:fix": "eslint . --fix",
"typecheck": "tsc -p tsconfig.json",
"build": "yarn run typecheck",
"bin:dev": "npx ts-node dist/serve-bin.js --port 8080 --package-path fixie"
},
"dependencies": {
"@opentelemetry/api": "^1.4.1",
"@opentelemetry/api-logs": "^0.41.1",
"@opentelemetry/exporter-logs-otlp-grpc": "^0.41.1",
"@opentelemetry/exporter-trace-otlp-grpc": "^0.41.1",
"@opentelemetry/instrumentation-fastify": "^0.32.0",
"@opentelemetry/instrumentation-fetch": "^0.41.1",
"@opentelemetry/instrumentation-http": "^0.41.2",
"@opentelemetry/sdk-logs": "^0.41.1",
"@opentelemetry/sdk-node": "^0.41.1",
"ai-jsx": "*",
"dotenv": "^16.3.1",
"fastify": "^4.20.0",
"yargs": "^17.7.2"
},
"bin": {
"serve-bin": "dist/serve-bin.js"
},
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"default": "./dist/index.cjs"
}
}
}
"name": "fixie",
"version": "1.0.0",
"private": true,
mdwelsh marked this conversation as resolved.
Show resolved Hide resolved
"license": "MIT",
"type": "module",
"scripts": {
"build": "tsc",
"start": "node dist/main.js",
"build-start": "yarn run build && yarn run start",
"format": "prettier --write .",
"lint": "eslint ."
mdwelsh marked this conversation as resolved.
Show resolved Hide resolved
},
"files": [
"dist"
],
"bin": "./dist/main.js",
"dependencies": {
"commander": "^11.0.0",
"eslint": "^8.44.0",
mdwelsh marked this conversation as resolved.
Show resolved Hide resolved
"open": "^9.1.0",
"terminal-kit": "^3.0.0"
},
"devDependencies": {
"@types/node": "^20.4.1",
"@types/terminal-kit": "^2.5.1",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"prettier": "^3.0.0",
"typescript": "5.1.3"
}
}
156 changes: 156 additions & 0 deletions packages/fixie/src/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/**
* A client to the Fixie AI platform.
*/
export class FixieClient {
url!: string;
apiKey!: string;

/** Use Create() instead. */
mdwelsh marked this conversation as resolved.
Show resolved Hide resolved
constructor() {}

/**
* Create a new Octopus Farmer client.
mdwelsh marked this conversation as resolved.
Show resolved Hide resolved
* @param url The URL of the Fixie API server.
*/
public static async Create(url: string): Promise<FixieClient> {
mdwelsh marked this conversation as resolved.
Show resolved Hide resolved
const client = new FixieClient();
client.url = url;
const apiKey = process.env.FIXIE_API_KEY;
if (!apiKey) {
throw new Error(
'Must set the FIXIE_API_KEY environment variable. This can be found at: https://app.fixie.ai/profile'
mdwelsh marked this conversation as resolved.
Show resolved Hide resolved
);
}
client.apiKey = apiKey;
return client;
}

async request(path: string, body?: any): Promise<any> {
let res;
if (body) {
body = JSON.stringify(body);
res = await fetch(`${this.url}${path}`, {
method: 'POST',
headers: {
Authorization: `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
},
body,
});
} else {
res = await fetch(`${this.url}${path}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${this.apiKey}`,
},
});
}
if (!res.ok) {
throw new Error(`Failed to access Fixie API ${this.url}${path}: ${res.statusText}`);
}
return res.json();
}

// Read the state of the current game.
mdwelsh marked this conversation as resolved.
Show resolved Hide resolved
async userInfo(): Promise<any> {
return this.request('/api/user');
}

async listCorpora(): Promise<any> {
return this.request('/api/v1/corpora');
}

async getCorpus(corpusId: string): Promise<any> {
return this.request(`/api/v1/corpora/${corpusId}`);
}

async createCorpus(name?: string): Promise<any> {
mdwelsh marked this conversation as resolved.
Show resolved Hide resolved
const body = {
name,
sources: [],
};
return this.request(`/api/v1/corpora`, body);
}

async queryCorpus(corpusId: string, query: string, pageSize?: number): Promise<any> {
const body = {
corpus_id: corpusId,
query,
page_size: pageSize,
};
return this.request(`/api/v1/corpora/${corpusId}:query`, body);
}

async listCorpusSources(corpusId: string): Promise<any> {
return this.request(`/api/v1/corpora/${corpusId}/sources`);
}

async getCorpusSource(corpusId: string, sourceId: string): Promise<any> {
return this.request(`/api/v1/corpora/${corpusId}/sources/${sourceId}`);
}

async addCorpusSource(corpusId: string, urlPattern: string): Promise<any> {
const body = {
corpus_id: corpusId,
source: {
corpus_id: corpusId,
load_spec: { web: { start_urls: [urlPattern] } },
process_steps: [
{
name: 'markdownify',
relevant_document_types: {
include: { mime_types: ['text/html'] },
},
html_to_markdown: {},
},
],
embed_specs: [
{
name: 'markdown',
relevant_document_types: {
include: { mime_types: ['text/markdown'] },
},
max_chunk_size: 1000,
chunk_overlap: 100,
splits: ['\n\n', '\n', ' ', ''],
},
{
name: 'plain',
relevant_document_types: {
include: { mime_types: ['text/plain'] },
},
max_chunk_size: 1000,
chunk_overlap: 100,
splits: ['\n\n', '\n', ' ', ''],
},
],
},
};

return this.request(`/api/v1/corpora/${corpusId}/sources`, body);
}

async refreshCorpusSource(corpusId: string, sourceId: string): Promise<any> {
const body = {
corpus_id: corpusId,
source_id: sourceId,
};
return this.request(`/api/v1/corpora/${corpusId}/sources/${sourceId}:refresh`, body);
}

async listCorpusSourceJobs(corpusId: string, sourceId: string): Promise<any> {
return this.request(`/api/v1/corpora/${corpusId}/sources/${sourceId}/jobs`);
}

async getCorpusSourceJob(corpusId: string, sourceId: string, jobId: string): Promise<any> {
return this.request(`/api/v1/corpora/${corpusId}/sources/${sourceId}/jobs/${jobId}`);
}

async listCorpusDocs(corpusId: string): Promise<any> {
return this.request(`/api/v1/corpora/${corpusId}/documents`);
}

async getCorpusDoc(corpusId: string, docId: string): Promise<any> {
return this.request(`/api/v1/corpora/${corpusId}/documents/${docId}`);
}
}
Loading
Loading