Skip to content

Commit

Permalink
Use AssemblyAI Node SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
Swimburger committed Oct 24, 2023
1 parent 86b09b0 commit 5e0522c
Show file tree
Hide file tree
Showing 85 changed files with 1,726 additions and 225 deletions.
898 changes: 884 additions & 14 deletions .pnp.cjs

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
3 changes: 2 additions & 1 deletion packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
"execa": "^8.0.1",
"rollup-plugin-visualizer": "^5.9.2",
"semver": "^7.5.4",
"tsx": "^3.12.7"
"tsx": "^3.12.7",
"vite-plugin-node-polyfills": "^0.15.0"
}
}
4 changes: 4 additions & 0 deletions packages/app/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import topLevelAwait from 'vite-plugin-top-level-await';
import { resolve } from 'node:path';
import { visualizer } from 'rollup-plugin-visualizer';
import { splitVendorChunkPlugin } from 'vite';
import { nodePolyfills } from 'vite-plugin-node-polyfills'

// https://vitejs.dev/config/
export default defineConfig({
Expand Down Expand Up @@ -46,5 +47,8 @@ export default defineConfig({
(monacoEditorPlugin as any).default({}),
topLevelAwait(),
splitVendorChunkPlugin(),
nodePolyfills({
include: ['fs', 'stream', '_stream_writable', 'buffer', 'events']
}),
],
});
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"dependencies": {
"@gentrace/core": "^2.1.15",
"@huggingface/inference": "^2.6.1",
"assemblyai": "^3.0.0",
"autoevals": "^0.0.16",
"crypto-js": "^4.1.1",
"emittery": "^1.0.1",
Expand Down
33 changes: 5 additions & 28 deletions packages/core/src/plugins/assemblyAi/LemurActionItemsNode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { nanoid } from 'nanoid/non-secure';
import { dedent } from 'ts-dedent';
import { AssemblyAI, type LemurActionItemsParameters } from 'assemblyai';
import {
type ChartNode,
type EditorDefinition,
Expand All @@ -16,7 +17,6 @@ import {
import { pluginNodeDefinition } from '../../model/NodeDefinition.js';
import {
type LemurNodeData,
type LemurParams,
getApiKey,
getLemurParams,
lemurEditorDefinitions,
Expand All @@ -25,9 +25,7 @@ import {

export type LemurActionItemsNode = ChartNode<'assemblyAiLemurActionItems', LemurActionItemsNodeData>;

export type LemurActionItemsNodeData = LemurNodeData & {
answer_format?: string;
};
export type LemurActionItemsNodeData = LemurNodeData;

export const LemurActionItemsNodeImpl: PluginNodeImpl<LemurActionItemsNode> = {
create(): LemurActionItemsNode {
Expand Down Expand Up @@ -95,15 +93,11 @@ export const LemurActionItemsNodeImpl: PluginNodeImpl<LemurActionItemsNode> = {

async process(data, inputs: Inputs, context: InternalProcessContext): Promise<Outputs> {
const apiKey = getApiKey(context);
const params: LemurParams & {
answer_format?: string;
} = getLemurParams(inputs, data);
const client = new AssemblyAI({ apiKey });

if (data.answer_format) {
params.answer_format = data.answer_format;
}
const params: LemurActionItemsParameters = getLemurParams(inputs, data);

const { response } = await runLemurActionItems(apiKey, params);
const { response } = await client.lemur.actionItems(params);

return {
['response' as PortId]: {
Expand All @@ -114,21 +108,4 @@ export const LemurActionItemsNodeImpl: PluginNodeImpl<LemurActionItemsNode> = {
},
};

async function runLemurActionItems(apiToken: string, params: object) {
const response = await fetch('https://api.assemblyai.com/lemur/v3/generate/action-items', {
method: 'POST',
body: JSON.stringify(params),
headers: {
authorization: apiToken,
},
});
const body = await response.json();
if (response.status !== 200) {
if ('error' in body) throw new Error(body.error);
throw new Error(`LeMUR Action Items failed with status ${response.status}`);
}

return body as { response: string };
}

export const lemurActionItemsNode = pluginNodeDefinition(LemurActionItemsNodeImpl, 'LeMUR Action Items');
49 changes: 10 additions & 39 deletions packages/core/src/plugins/assemblyAi/LemurQaNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ import {
} from '../../index.js';
import {
type LemurNodeData,
type LemurParams,
getApiKey,
getLemurParams,
lemurEditorDefinitions,
lemurTranscriptIdsInputDefinition,
} from './lemurHelpers.js';
import { coerceType } from '../../utils/coerceType.js';
import { pluginNodeDefinition } from '../../model/NodeDefinition.js';
import { AssemblyAI, type LemurQuestion, type LemurQuestionAnswerParameters } from 'assemblyai';

export type LemurQaNode = ChartNode<'assemblyAiLemurQa', LemurQaNodeData>;

Expand Down Expand Up @@ -123,17 +123,16 @@ export const LemurQaNodeImpl = {

async process(data, inputs: Inputs, context: InternalProcessContext): Promise<Outputs> {
const apiKey = getApiKey(context);
const client = new AssemblyAI({ apiKey });

const questions = getQuestions(inputs).map((question) => applyQuestionEditors(data, question));

const params: LemurParams & {
questions: Question[];
} = {
const params: LemurQuestionAnswerParameters = {
questions,
...getLemurParams(inputs, data),
};

const { response } = await runLemurQa(apiKey, params);
const { response } = await client.lemur.questionAnswer(params);
return {
['response' as PortId]: {
type: 'object[]',
Expand All @@ -143,7 +142,7 @@ export const LemurQaNodeImpl = {
},
} satisfies PluginNodeImpl<LemurQaNode>;

function getQuestions(inputs: Inputs): Question[] {
function getQuestions(inputs: Inputs): LemurQuestion[] {
const input = inputs['questions' as PortId] as
| StringDataValue
| StringArrayDataValue
Expand All @@ -163,21 +162,21 @@ function getQuestions(inputs: Inputs): Question[] {
} else if (input.type === 'string[]') {
return coerceType(input, 'string[]').map((question) => ({ question }));
} else if (input.type === 'object') {
return [coerceType(input, 'object')] as Question[];
return [coerceType(input, 'object')] as LemurQuestion[];
} else if (input.type === 'object[]') {
return coerceType(input, 'object[]') as unknown as Question[];
return coerceType(input, 'object[]') as unknown as LemurQuestion[];
} else if (input.type === 'any' && typeof input.value === 'string') {
return [
{
question: coerceType(input, 'string'),
},
];
} else if ((input.type === 'any' && Array.isArray(input.value)) || input.type === 'any[]') {
return (input.value as any[]).map<Question>((question: any) => {
return (input.value as any[]).map<LemurQuestion>((question: any) => {
if (typeof question === 'string') {
return { question };
} else if (typeof question === 'object') {
return question as Question;
return question as LemurQuestion;
} else {
throw new Error('Question must be a string or object.');
}
Expand All @@ -186,7 +185,7 @@ function getQuestions(inputs: Inputs): Question[] {
throw new Error('Questions must be a string, string[], a question object, or an array of question objects.');
}

function applyQuestionEditors(data: LemurQaNodeData, question: Question): Question {
function applyQuestionEditors(data: LemurQaNodeData, question: LemurQuestion): LemurQuestion {
if (!('answer_format' in question) && data.questions_answer_format) {
question.answer_format = data.questions_answer_format;
}
Expand All @@ -200,32 +199,4 @@ function applyQuestionEditors(data: LemurQaNodeData, question: Question): Questi
return question;
}

async function runLemurQa(apiToken: string, params: object) {
const response = await fetch('https://api.assemblyai.com/lemur/v3/generate/question-answer', {
method: 'POST',
body: JSON.stringify(params),
headers: {
authorization: apiToken,
},
});
const body = await response.json();
if (response.status !== 200) {
if ('error' in body) throw new Error(body.error);
throw new Error(`LeMUR QA failed with status ${response.status}`);
}

return body as { response: QuestionAnswer[] };
}

type Question = {
question: string;
context?: string;
answer_format?: string;
answer_options?: string[];
};
type QuestionAnswer = {
question: string;
answer: string;
};

export const lemurQaNode = pluginNodeDefinition(LemurQaNodeImpl, 'LeMUR Q&A');
26 changes: 4 additions & 22 deletions packages/core/src/plugins/assemblyAi/LemurSummaryNode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { nanoid } from 'nanoid/non-secure';
import { dedent } from 'ts-dedent';
import { AssemblyAI, type LemurSummaryParameters } from 'assemblyai';
import {
type ChartNode,
type EditorDefinition,
Expand All @@ -15,7 +16,6 @@ import {
} from '../../index.js';
import {
type LemurNodeData,
type LemurParams,
getApiKey,
getLemurParams,
lemurEditorDefinitions,
Expand Down Expand Up @@ -95,15 +95,14 @@ export const LemurSummaryNodeImpl: PluginNodeImpl<LemurSummaryNode> = {

async process(data, inputs: Inputs, context: InternalProcessContext): Promise<Outputs> {
const apiKey = getApiKey(context);
const params: LemurParams & {
answer_format?: string;
} = getLemurParams(inputs, data);
const client = new AssemblyAI({ apiKey });
const params: LemurSummaryParameters = getLemurParams(inputs, data);

if (data.answer_format) {
params.answer_format = data.answer_format;
}

const { response } = await runLemurSummary(apiKey, params);
const { response } = await client.lemur.summary(params);

return {
['response' as PortId]: {
Expand All @@ -114,21 +113,4 @@ export const LemurSummaryNodeImpl: PluginNodeImpl<LemurSummaryNode> = {
},
};

async function runLemurSummary(apiToken: string, params: object) {
const response = await fetch('https://api.assemblyai.com/lemur/v3/generate/summary', {
method: 'POST',
body: JSON.stringify(params),
headers: {
authorization: apiToken,
},
});
const body = await response.json();
if (response.status !== 200) {
if ('error' in body) throw new Error(body.error);
throw new Error(`LeMUR Summary failed with status ${response.status}`);
}

return body as { response: string };
}

export const lemurSummaryNode = pluginNodeDefinition(LemurSummaryNodeImpl, 'LeMUR Summary');
26 changes: 4 additions & 22 deletions packages/core/src/plugins/assemblyAi/LemurTaskNode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { nanoid } from 'nanoid/non-secure';
import { dedent } from 'ts-dedent';
import { AssemblyAI, type LemurTaskParameters } from 'assemblyai';
import {
type ChartNode,
type EditorDefinition,
Expand All @@ -15,7 +16,6 @@ import {
} from '../../index.js';
import {
type LemurNodeData,
type LemurParams,
getApiKey,
getLemurParams,
lemurEditorDefinitions,
Expand Down Expand Up @@ -96,15 +96,14 @@ export const LemurTaskNodeImpl: PluginNodeImpl<LemurTaskNode> = {

async process(data, inputs: Inputs, context: InternalProcessContext): Promise<Outputs> {
const apiKey = getApiKey(context);
const params: Omit<LemurParams, 'context'> & {
prompt: string;
} = {
const client = new AssemblyAI(apiKey);
const params: LemurTaskParameters = {
prompt: coerceTypeOptional(inputs['prompt' as PortId], 'string') || data.prompt || '',
...getLemurParams(inputs, data),
};
if (!params.prompt) throw new Error('Prompt must be provided.');

const { response } = await runLemurTask(apiKey, params);
const { response } = await client.lemur.task(params);

return {
['response' as PortId]: {
Expand All @@ -115,21 +114,4 @@ export const LemurTaskNodeImpl: PluginNodeImpl<LemurTaskNode> = {
},
};

async function runLemurTask(apiToken: string, params: object) {
const response = await fetch('https://api.assemblyai.com/lemur/v3/generate/task', {
method: 'POST',
body: JSON.stringify(params),
headers: {
authorization: apiToken,
},
});
const body = await response.json();
if (response.status !== 200) {
if ('error' in body) throw new Error(body.error);
throw new Error(`LeMUR Task failed with status ${response.status}`);
}

return body as { response: string };
}

export const lemurTaskNode = pluginNodeDefinition(LemurTaskNodeImpl, 'LeMUR Task');
Loading

0 comments on commit 5e0522c

Please sign in to comment.