Skip to content

Commit

Permalink
community[minor]: Taskade Project Loader (#5927)
Browse files Browse the repository at this point in the history
Co-authored-by: jacoblee93 <[email protected]>
  • Loading branch information
yeouchien and jacoblee93 authored Jul 2, 2024
1 parent b35812c commit 5076dd3
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
hide_table_of_contents: true
---

# Taskade

[Taskade](https://www.taskade.com) is the ultimate tool for AI-driven writing, project management, and task automation. Designed to be your second brain, Taskade simplifies project execution and enhances team collaboration from start to finish.

## Overview

With [Taskade](https://www.taskade.com), you can build, train, and deploy your own team of AI agents to automate tasks and streamline workflows. Taskade features a seamless blend of ideation, collaboration, and execution tools—from structured lists to modern tables and mind maps, all customizable to fit your unique workflow and adapt to your needs.

import CodeBlock from "@theme/CodeBlock";
import Example from "@examples/document_loaders/taskade.ts";

<CodeBlock language="typescript">{Example}</CodeBlock>

You can find your Taskade project id by opening the project in your browser and extracting them from the URL:

```
https://www.taskade.com/d/<YOUR PROJECT ID HERE>
```
9 changes: 9 additions & 0 deletions examples/src/document_loaders/taskade.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { TaskadeProjectLoader } from "@langchain/community/document_loaders/web/taskade";

const loader = new TaskadeProjectLoader({
personalAccessToken: "TASKADE_PERSONAL_ACCESS_TOKEN", // or load it from process.env.TASKADE_PERSONAL_ACCESS_TOKEN
projectId: "projectId",
});
const docs = await loader.load();

console.log({ docs });
4 changes: 4 additions & 0 deletions libs/langchain-community/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,10 @@ document_loaders/web/github.cjs
document_loaders/web/github.js
document_loaders/web/github.d.ts
document_loaders/web/github.d.cts
document_loaders/web/taskade.cjs
document_loaders/web/taskade.js
document_loaders/web/taskade.d.ts
document_loaders/web/taskade.d.cts
document_loaders/web/notionapi.cjs
document_loaders/web/notionapi.js
document_loaders/web/notionapi.d.ts
Expand Down
2 changes: 2 additions & 0 deletions libs/langchain-community/langchain.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ export const config = {
"document_loaders/web/figma": "document_loaders/web/figma",
"document_loaders/web/firecrawl": "document_loaders/web/firecrawl",
"document_loaders/web/github": "document_loaders/web/github",
"document_loaders/web/taskade": "document_loaders/web/taskade",
"document_loaders/web/notionapi": "document_loaders/web/notionapi",
"document_loaders/web/pdf": "document_loaders/web/pdf",
"document_loaders/web/recursive_url": "document_loaders/web/recursive_url",
Expand Down Expand Up @@ -491,6 +492,7 @@ export const config = {
"document_loaders/web/firecrawl",
"document_loaders/web/github",
"document_loaders/web/pdf",
"document_loaders/web/taskade",
"document_loaders/web/notionapi",
"document_loaders/web/recursive_url",
"document_loaders/web/s3",
Expand Down
13 changes: 13 additions & 0 deletions libs/langchain-community/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2734,6 +2734,15 @@
"import": "./document_loaders/web/github.js",
"require": "./document_loaders/web/github.cjs"
},
"./document_loaders/web/taskade": {
"types": {
"import": "./document_loaders/web/taskade.d.ts",
"require": "./document_loaders/web/taskade.d.cts",
"default": "./document_loaders/web/taskade.d.ts"
},
"import": "./document_loaders/web/taskade.js",
"require": "./document_loaders/web/taskade.cjs"
},
"./document_loaders/web/notionapi": {
"types": {
"import": "./document_loaders/web/notionapi.d.ts",
Expand Down Expand Up @@ -3948,6 +3957,10 @@
"document_loaders/web/github.js",
"document_loaders/web/github.d.ts",
"document_loaders/web/github.d.cts",
"document_loaders/web/taskade.cjs",
"document_loaders/web/taskade.js",
"document_loaders/web/taskade.d.ts",
"document_loaders/web/taskade.d.cts",
"document_loaders/web/notionapi.cjs",
"document_loaders/web/notionapi.js",
"document_loaders/web/notionapi.d.ts",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* eslint-disable no-process-env */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { test } from "@jest/globals";
import { TaskadeProjectLoader } from "../web/taskade.js";

test.skip("Test TaskadeProjectLoader", async () => {
const loader = new TaskadeProjectLoader({
personalAccessToken: process.env.TASKADE_PERSONAL_ACCESS_TOKEN!,
projectId: process.env.TASKADE_PROJECT_ID!,
});
const documents = await loader.load();
console.log(documents[0].pageContent);
});
125 changes: 125 additions & 0 deletions libs/langchain-community/src/document_loaders/web/taskade.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { getEnvironmentVariable } from "@langchain/core/utils/env";
import { Document } from "@langchain/core/documents";
import { BaseDocumentLoader } from "@langchain/core/document_loaders/base";

/**
* Interface representing the parameters for configuring the TaskadeLoader.
* It includes optional properties for the personal access token and project id.
*/
export interface TaskadeLoaderParams {
personalAccessToken?: string;
projectId: string;
}

/**
* Interface representing a Taskade project. It includes properties for the
* id, text, parentId and completed.
*/
export interface TaskadeProject {
tasks: Array<{
id: string;
text: string;
parentId: string;
completed: boolean;
}>;
}

/**
* Class representing a document loader for loading Taskade project. It
* extends the BaseDocumentLoader and implements the TaskadeLoaderParams
* interface. The constructor takes a config object as a parameter, which
* contains the personal access token and project ID.
* @example
* ```typescript
* const loader = new TaskadeProjectLoader({
* personalAccessToken: "TASKADE_PERSONAL_ACCESS_TOKEN",
* projectId: "projectId",
* });
* const docs = await loader.load();
* ```
*/
export class TaskadeProjectLoader
extends BaseDocumentLoader
implements TaskadeLoaderParams
{
public readonly personalAccessToken?: string;

public readonly projectId: string;

private headers: Record<string, string> = {};

constructor({
personalAccessToken = getEnvironmentVariable(
"TASKADE_PERSONAL_ACCESS_TOKEN"
),
projectId,
}: TaskadeLoaderParams) {
super();
this.personalAccessToken = personalAccessToken;
this.projectId = projectId;

if (this.personalAccessToken) {
this.headers = {
Authorization: `Bearer ${this.personalAccessToken}`,
};
}
}

/**
* Fetches the Taskade project using the Taskade API and returns it as a
* TaskadeProject object.
* @returns A Promise that resolves to a TaskadeProject object.
*/
private async getTaskadeProject(): Promise<TaskadeProject> {
const tasks = [];
let after: string | null = null;
let hasMoreTasks = true;
while (hasMoreTasks) {
const queryParamsString: string = new URLSearchParams({
limit: "100",
...(after == null ? {} : { after }),
}).toString();
const url = `https://www.taskade.com/api/v1/projects/${this.projectId}/tasks?${queryParamsString}`;

const response = await fetch(url, { headers: this.headers });
const data = await response.json();

if (!response.ok) {
throw new Error(
`Unable to get Taskade project: ${response.status} ${JSON.stringify(
data
)}`
);
}

if (!data) {
throw new Error("Unable to get Taskade project");
}

if (data.items.length === 0) {
hasMoreTasks = false;
} else {
after = data.items[data.items.length - 1].id;
}

tasks.push(...data.items);
}

return { tasks };
}

/**
* Fetches the Taskade project using the Taskade API, creates a Document instance
* with the JSON representation of the file as the page content and the
* API URL as the metadata, and returns it.
* @returns A Promise that resolves to an array of Document instances.
*/
public async load(): Promise<Document[]> {
const data = await this.getTaskadeProject();

const metadata = { projectId: this.projectId };
const text = data.tasks.map((t) => t.text).join("\n");

return [new Document({ pageContent: text, metadata })];
}
}
1 change: 1 addition & 0 deletions libs/langchain-community/src/load/import_constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ export const optionalImportEntrypoints: string[] = [
"langchain_community/document_loaders/web/figma",
"langchain_community/document_loaders/web/firecrawl",
"langchain_community/document_loaders/web/github",
"langchain_community/document_loaders/web/taskade",
"langchain_community/document_loaders/web/notionapi",
"langchain_community/document_loaders/web/pdf",
"langchain_community/document_loaders/web/recursive_url",
Expand Down

0 comments on commit 5076dd3

Please sign in to comment.