chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import type { AsanaAddCommentParams, AsanaAddCommentResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaAddCommentTool: ToolConfig<AsanaAddCommentParams, AsanaAddCommentResponse> = {
|
||||
id: 'asana_add_comment',
|
||||
name: 'Asana Add Comment',
|
||||
description: 'Add a comment (story) to an Asana task',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
taskGid: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Asana task GID (numeric string)',
|
||||
},
|
||||
text: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The text content of the comment',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/add-comment',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
taskGid: params.taskGid,
|
||||
text: params.text,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: false,
|
||||
output: {},
|
||||
error: 'Empty response from Asana',
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
gid: { type: 'string', description: 'Comment globally unique identifier' },
|
||||
text: { type: 'string', description: 'Comment text content' },
|
||||
created_at: { type: 'string', description: 'Comment creation timestamp' },
|
||||
created_by: {
|
||||
type: 'object',
|
||||
description: 'Comment author details',
|
||||
properties: {
|
||||
gid: { type: 'string', description: 'Author GID' },
|
||||
name: { type: 'string', description: 'Author name' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import type { AsanaAddFollowersParams, AsanaAddFollowersResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaAddFollowersTool: ToolConfig<AsanaAddFollowersParams, AsanaAddFollowersResponse> =
|
||||
{
|
||||
id: 'asana_add_followers',
|
||||
name: 'Asana Add Followers',
|
||||
description: 'Add one or more followers to an Asana task',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
taskGid: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'GID of the Asana task (numeric string)',
|
||||
},
|
||||
followers: {
|
||||
type: 'array',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Array of user GIDs to add as followers to the task',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/add-followers',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
taskGid: params.taskGid,
|
||||
followers: params.followers,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: false,
|
||||
output: { ts: new Date().toISOString(), gid: '', name: '', followers: [] },
|
||||
error: 'Empty response from Asana',
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
gid: { type: 'string', description: 'Task globally unique identifier' },
|
||||
name: { type: 'string', description: 'Task name' },
|
||||
followers: {
|
||||
type: 'array',
|
||||
description: 'Current followers on the task after the update',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
gid: { type: 'string', description: 'Follower GID' },
|
||||
name: { type: 'string', description: 'Follower name' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import type { AsanaCreateProjectParams, AsanaProjectRecordResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaCreateProjectTool: ToolConfig<
|
||||
AsanaCreateProjectParams,
|
||||
AsanaProjectRecordResponse
|
||||
> = {
|
||||
id: 'asana_create_project',
|
||||
name: 'Asana Create Project',
|
||||
description: 'Create a new project in an Asana workspace',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
workspace: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Asana workspace GID (numeric string) where the project will be created',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the project',
|
||||
},
|
||||
notes: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Notes or description for the project',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/create-project',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
workspace: params.workspace,
|
||||
name: params.name,
|
||||
notes: params.notes,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: false,
|
||||
output: { ts: new Date().toISOString(), gid: '', name: '', notes: '' },
|
||||
error: 'Empty response from Asana',
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
gid: { type: 'string', description: 'Project globally unique identifier' },
|
||||
name: { type: 'string', description: 'Project name' },
|
||||
notes: { type: 'string', description: 'Project notes or description' },
|
||||
archived: { type: 'boolean', description: 'Whether the project is archived' },
|
||||
color: { type: 'string', description: 'Project color' },
|
||||
created_at: { type: 'string', description: 'Project creation timestamp' },
|
||||
modified_at: { type: 'string', description: 'Project last modified timestamp' },
|
||||
permalink_url: { type: 'string', description: 'URL to the project in Asana' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import type { AsanaCreateSectionParams, AsanaSectionResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaCreateSectionTool: ToolConfig<AsanaCreateSectionParams, AsanaSectionResponse> = {
|
||||
id: 'asana_create_section',
|
||||
name: 'Asana Create Section',
|
||||
description: 'Create a new section in an Asana project',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
projectGid: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'GID of the Asana project (numeric string) to add the section to',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the section',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/create-section',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
projectGid: params.projectGid,
|
||||
name: params.name,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: false,
|
||||
output: { ts: new Date().toISOString(), gid: '', name: '' },
|
||||
error: 'Empty response from Asana',
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
gid: { type: 'string', description: 'Section globally unique identifier' },
|
||||
name: { type: 'string', description: 'Section name' },
|
||||
created_at: { type: 'string', description: 'Section creation timestamp' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
import type { AsanaCreateSubtaskParams, AsanaCreateTaskResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaCreateSubtaskTool: ToolConfig<AsanaCreateSubtaskParams, AsanaCreateTaskResponse> =
|
||||
{
|
||||
id: 'asana_create_subtask',
|
||||
name: 'Asana Create Subtask',
|
||||
description: 'Create a subtask under an existing Asana task',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
taskGid: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'GID of the parent Asana task (numeric string)',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the subtask',
|
||||
},
|
||||
notes: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Notes or description for the subtask',
|
||||
},
|
||||
assignee: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'User GID to assign the subtask to',
|
||||
},
|
||||
due_on: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Due date in YYYY-MM-DD format',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/create-subtask',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
taskGid: params.taskGid,
|
||||
name: params.name,
|
||||
notes: params.notes,
|
||||
assignee: params.assignee,
|
||||
due_on: params.due_on,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: false,
|
||||
output: {
|
||||
ts: new Date().toISOString(),
|
||||
gid: '',
|
||||
name: '',
|
||||
notes: '',
|
||||
completed: false,
|
||||
created_at: new Date().toISOString(),
|
||||
permalink_url: '',
|
||||
},
|
||||
error: 'Empty response from Asana',
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
gid: { type: 'string', description: 'Subtask globally unique identifier' },
|
||||
name: { type: 'string', description: 'Subtask name' },
|
||||
notes: { type: 'string', description: 'Subtask notes or description' },
|
||||
completed: { type: 'boolean', description: 'Whether the subtask is completed' },
|
||||
created_at: { type: 'string', description: 'Subtask creation timestamp' },
|
||||
permalink_url: { type: 'string', description: 'URL to the subtask in Asana' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
import type { AsanaCreateTaskParams, AsanaCreateTaskResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaCreateTaskTool: ToolConfig<AsanaCreateTaskParams, AsanaCreateTaskResponse> = {
|
||||
id: 'asana_create_task',
|
||||
name: 'Asana Create Task',
|
||||
description: 'Create a new task in Asana',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
workspace: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Asana workspace GID (numeric string) where the task will be created',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the task',
|
||||
},
|
||||
notes: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Notes or description for the task',
|
||||
},
|
||||
assignee: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'User GID to assign the task to',
|
||||
},
|
||||
due_on: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Due date in YYYY-MM-DD format',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/create-task',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
workspace: params.workspace,
|
||||
name: params.name,
|
||||
notes: params.notes,
|
||||
assignee: params.assignee,
|
||||
due_on: params.due_on,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
ts: new Date().toISOString(),
|
||||
gid: 'unknown',
|
||||
name: 'Task created successfully',
|
||||
notes: '',
|
||||
completed: false,
|
||||
created_at: new Date().toISOString(),
|
||||
permalink_url: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
gid: { type: 'string', description: 'Task globally unique identifier' },
|
||||
name: { type: 'string', description: 'Task name' },
|
||||
notes: { type: 'string', description: 'Task notes or description' },
|
||||
completed: { type: 'boolean', description: 'Whether the task is completed' },
|
||||
created_at: { type: 'string', description: 'Task creation timestamp' },
|
||||
permalink_url: { type: 'string', description: 'URL to the task in Asana' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import type { AsanaDeleteTaskParams, AsanaDeleteTaskResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaDeleteTaskTool: ToolConfig<AsanaDeleteTaskParams, AsanaDeleteTaskResponse> = {
|
||||
id: 'asana_delete_task',
|
||||
name: 'Asana Delete Task',
|
||||
description: 'Delete an Asana task by its GID (moves it to the trash)',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
taskGid: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'GID of the Asana task to delete (numeric string)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/delete-task',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
taskGid: params.taskGid,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: false,
|
||||
output: { ts: new Date().toISOString(), gid: '', deleted: true },
|
||||
error: 'Empty response from Asana',
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
gid: { type: 'string', description: 'GID of the deleted task' },
|
||||
deleted: { type: 'boolean', description: 'Whether the task was deleted' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import type { AsanaGetProjectParams, AsanaProjectRecordResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaGetProjectTool: ToolConfig<AsanaGetProjectParams, AsanaProjectRecordResponse> = {
|
||||
id: 'asana_get_project',
|
||||
name: 'Asana Get Project',
|
||||
description: 'Retrieve a single Asana project by its GID',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
projectGid: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Asana project GID (numeric string) to retrieve',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/get-project',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
projectGid: params.projectGid,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: false,
|
||||
output: { ts: new Date().toISOString(), gid: '', name: '', notes: '' },
|
||||
error: 'Empty response from Asana',
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
gid: { type: 'string', description: 'Project globally unique identifier' },
|
||||
name: { type: 'string', description: 'Project name' },
|
||||
notes: { type: 'string', description: 'Project notes or description' },
|
||||
archived: { type: 'boolean', description: 'Whether the project is archived' },
|
||||
color: { type: 'string', description: 'Project color' },
|
||||
created_at: { type: 'string', description: 'Project creation timestamp' },
|
||||
modified_at: { type: 'string', description: 'Project last modified timestamp' },
|
||||
permalink_url: { type: 'string', description: 'URL to the project in Asana' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import type { AsanaGetProjectsParams, AsanaGetProjectsResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaGetProjectsTool: ToolConfig<AsanaGetProjectsParams, AsanaGetProjectsResponse> = {
|
||||
id: 'asana_get_projects',
|
||||
name: 'Asana Get Projects',
|
||||
description: 'Retrieve all projects from an Asana workspace',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
workspace: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Asana workspace GID (numeric string) to retrieve projects from',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/get-projects',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
workspace: params.workspace,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: false,
|
||||
output: {},
|
||||
error: 'Empty response from Asana',
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
projects: {
|
||||
type: 'array',
|
||||
description: 'Array of projects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
gid: { type: 'string', description: 'Project GID' },
|
||||
name: { type: 'string', description: 'Project name' },
|
||||
resource_type: { type: 'string', description: 'Resource type (project)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
import type { AsanaGetTaskParams, AsanaGetTaskResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaGetTaskTool: ToolConfig<AsanaGetTaskParams, AsanaGetTaskResponse> = {
|
||||
id: 'asana_get_task',
|
||||
name: 'Asana Get Task',
|
||||
description: 'Retrieve a single task by GID or get multiple tasks with filters',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
taskGid: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'The globally unique identifier (GID) of the task. If not provided, will get multiple tasks.',
|
||||
},
|
||||
workspace: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Asana workspace GID (numeric string) to filter tasks (required when not using taskGid)',
|
||||
},
|
||||
project: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Asana project GID (numeric string) to filter tasks',
|
||||
},
|
||||
limit: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of tasks to return (default: 50)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/get-task',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
taskGid: params.taskGid,
|
||||
workspace: params.workspace,
|
||||
project: params.project,
|
||||
limit: params.limit,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: false,
|
||||
output: {},
|
||||
error: 'Empty response from Asana',
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
gid: { type: 'string', description: 'Task globally unique identifier' },
|
||||
resource_type: { type: 'string', description: 'Resource type (task)' },
|
||||
resource_subtype: { type: 'string', description: 'Resource subtype' },
|
||||
name: { type: 'string', description: 'Task name' },
|
||||
notes: { type: 'string', description: 'Task notes or description' },
|
||||
completed: { type: 'boolean', description: 'Whether the task is completed' },
|
||||
assignee: {
|
||||
type: 'object',
|
||||
description: 'Assignee details',
|
||||
properties: {
|
||||
gid: { type: 'string', description: 'Assignee GID' },
|
||||
name: { type: 'string', description: 'Assignee name' },
|
||||
},
|
||||
},
|
||||
created_by: {
|
||||
type: 'object',
|
||||
description: 'Creator details',
|
||||
properties: {
|
||||
gid: { type: 'string', description: 'Creator GID' },
|
||||
name: { type: 'string', description: 'Creator name' },
|
||||
},
|
||||
},
|
||||
due_on: { type: 'string', description: 'Due date (YYYY-MM-DD)' },
|
||||
created_at: { type: 'string', description: 'Task creation timestamp' },
|
||||
modified_at: { type: 'string', description: 'Task last modified timestamp' },
|
||||
tasks: {
|
||||
type: 'array',
|
||||
description: 'Array of tasks (when fetching multiple)',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
gid: { type: 'string', description: 'Task GID' },
|
||||
name: { type: 'string', description: 'Task name' },
|
||||
completed: { type: 'boolean', description: 'Completion status' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { asanaAddCommentTool } from '@/tools/asana/add_comment'
|
||||
import { asanaAddFollowersTool } from '@/tools/asana/add_followers'
|
||||
import { asanaCreateProjectTool } from '@/tools/asana/create_project'
|
||||
import { asanaCreateSectionTool } from '@/tools/asana/create_section'
|
||||
import { asanaCreateSubtaskTool } from '@/tools/asana/create_subtask'
|
||||
import { asanaCreateTaskTool } from '@/tools/asana/create_task'
|
||||
import { asanaDeleteTaskTool } from '@/tools/asana/delete_task'
|
||||
import { asanaGetProjectTool } from '@/tools/asana/get_project'
|
||||
import { asanaGetProjectsTool } from '@/tools/asana/get_projects'
|
||||
import { asanaGetTaskTool } from '@/tools/asana/get_task'
|
||||
import { asanaListSectionsTool } from '@/tools/asana/list_sections'
|
||||
import { asanaListWorkspacesTool } from '@/tools/asana/list_workspaces'
|
||||
import { asanaSearchTasksTool } from '@/tools/asana/search_tasks'
|
||||
import { asanaUpdateTaskTool } from '@/tools/asana/update_task'
|
||||
|
||||
export { asanaGetTaskTool }
|
||||
export { asanaCreateTaskTool }
|
||||
export { asanaUpdateTaskTool }
|
||||
export { asanaGetProjectsTool }
|
||||
export { asanaSearchTasksTool }
|
||||
export { asanaAddCommentTool }
|
||||
export { asanaCreateProjectTool }
|
||||
export { asanaGetProjectTool }
|
||||
export { asanaListWorkspacesTool }
|
||||
export { asanaCreateSubtaskTool }
|
||||
export { asanaDeleteTaskTool }
|
||||
export { asanaAddFollowersTool }
|
||||
export { asanaCreateSectionTool }
|
||||
export { asanaListSectionsTool }
|
||||
@@ -0,0 +1,79 @@
|
||||
import type { AsanaListSectionsParams, AsanaListSectionsResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaListSectionsTool: ToolConfig<AsanaListSectionsParams, AsanaListSectionsResponse> =
|
||||
{
|
||||
id: 'asana_list_sections',
|
||||
name: 'Asana List Sections',
|
||||
description: 'List all sections in an Asana project',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
projectGid: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'GID of the Asana project (numeric string) to list sections from',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/list-sections',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
projectGid: params.projectGid,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: false,
|
||||
output: { ts: new Date().toISOString(), sections: [] },
|
||||
error: 'Empty response from Asana',
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
sections: {
|
||||
type: 'array',
|
||||
description: 'Array of sections in the project',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
gid: { type: 'string', description: 'Section GID' },
|
||||
name: { type: 'string', description: 'Section name' },
|
||||
resource_type: { type: 'string', description: 'Resource type (section)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import type { AsanaListWorkspacesParams, AsanaListWorkspacesResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaListWorkspacesTool: ToolConfig<
|
||||
AsanaListWorkspacesParams,
|
||||
AsanaListWorkspacesResponse
|
||||
> = {
|
||||
id: 'asana_list_workspaces',
|
||||
name: 'Asana List Workspaces',
|
||||
description: 'List all Asana workspaces and organizations the authenticated user belongs to',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/list-workspaces',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: false,
|
||||
output: { ts: new Date().toISOString(), workspaces: [] },
|
||||
error: 'Empty response from Asana',
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
workspaces: {
|
||||
type: 'array',
|
||||
description: 'Array of workspaces',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
gid: { type: 'string', description: 'Workspace GID' },
|
||||
name: { type: 'string', description: 'Workspace name' },
|
||||
resource_type: { type: 'string', description: 'Resource type (workspace)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
import type { AsanaSearchTasksParams, AsanaSearchTasksResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaSearchTasksTool: ToolConfig<AsanaSearchTasksParams, AsanaSearchTasksResponse> = {
|
||||
id: 'asana_search_tasks',
|
||||
name: 'Asana Search Tasks',
|
||||
description: 'Search for tasks in an Asana workspace',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
workspace: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Asana workspace GID (numeric string) to search tasks in',
|
||||
},
|
||||
text: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Text to search for in task names',
|
||||
},
|
||||
assignee: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter tasks by assignee user GID',
|
||||
},
|
||||
projects: {
|
||||
type: 'array',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Array of Asana project GIDs (numeric strings) to filter tasks by',
|
||||
},
|
||||
completed: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by completion status',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/search-tasks',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
workspace: params.workspace,
|
||||
text: params.text,
|
||||
assignee: params.assignee,
|
||||
projects: params.projects,
|
||||
completed: params.completed,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: false,
|
||||
output: {},
|
||||
error: 'Empty response from Asana',
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
tasks: {
|
||||
type: 'array',
|
||||
description: 'Array of matching tasks',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
gid: { type: 'string', description: 'Task GID' },
|
||||
resource_type: { type: 'string', description: 'Resource type' },
|
||||
resource_subtype: { type: 'string', description: 'Resource subtype' },
|
||||
name: { type: 'string', description: 'Task name' },
|
||||
notes: { type: 'string', description: 'Task notes' },
|
||||
completed: { type: 'boolean', description: 'Completion status' },
|
||||
assignee: {
|
||||
type: 'object',
|
||||
description: 'Assignee details',
|
||||
properties: {
|
||||
gid: { type: 'string', description: 'Assignee GID' },
|
||||
name: { type: 'string', description: 'Assignee name' },
|
||||
},
|
||||
},
|
||||
due_on: { type: 'string', description: 'Due date' },
|
||||
created_at: { type: 'string', description: 'Creation timestamp' },
|
||||
modified_at: { type: 'string', description: 'Modified timestamp' },
|
||||
},
|
||||
},
|
||||
},
|
||||
next_page: {
|
||||
type: 'object',
|
||||
description: 'Pagination info',
|
||||
properties: {
|
||||
offset: { type: 'string', description: 'Offset token' },
|
||||
path: { type: 'string', description: 'API path' },
|
||||
uri: { type: 'string', description: 'Full URI' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
import type { ToolResponse } from '@/tools/types'
|
||||
|
||||
export interface AsanaGetTaskParams {
|
||||
accessToken: string
|
||||
taskGid?: string
|
||||
workspace?: string
|
||||
project?: string
|
||||
limit?: number
|
||||
}
|
||||
|
||||
export interface AsanaGetTaskResponse extends ToolResponse {
|
||||
output: {
|
||||
ts: string
|
||||
gid?: string
|
||||
resource_type?: string
|
||||
resource_subtype?: string
|
||||
name?: string
|
||||
notes?: string
|
||||
completed?: boolean
|
||||
assignee?: {
|
||||
gid: string
|
||||
name: string
|
||||
}
|
||||
created_by?: {
|
||||
gid: string
|
||||
resource_type: string
|
||||
name: string
|
||||
}
|
||||
due_on?: string
|
||||
created_at?: string
|
||||
modified_at?: string
|
||||
tasks?: Array<{
|
||||
gid: string
|
||||
resource_type: string
|
||||
resource_subtype: string
|
||||
name: string
|
||||
notes?: string
|
||||
completed: boolean
|
||||
assignee?: {
|
||||
gid: string
|
||||
name: string
|
||||
}
|
||||
created_by?: {
|
||||
gid: string
|
||||
resource_type: string
|
||||
name: string
|
||||
}
|
||||
due_on?: string
|
||||
created_at: string
|
||||
modified_at: string
|
||||
}>
|
||||
next_page?: {
|
||||
offset: string
|
||||
path: string
|
||||
uri: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface AsanaCreateTaskParams {
|
||||
accessToken: string
|
||||
workspace: string
|
||||
name: string
|
||||
notes?: string
|
||||
assignee?: string
|
||||
due_on?: string
|
||||
}
|
||||
|
||||
export interface AsanaCreateTaskResponse extends ToolResponse {
|
||||
output: {
|
||||
ts: string
|
||||
gid: string
|
||||
name: string
|
||||
notes: string
|
||||
completed: boolean
|
||||
created_at: string
|
||||
permalink_url: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface AsanaUpdateTaskParams {
|
||||
accessToken: string
|
||||
taskGid: string
|
||||
name?: string
|
||||
notes?: string
|
||||
assignee?: string
|
||||
completed?: boolean
|
||||
due_on?: string
|
||||
}
|
||||
|
||||
export interface AsanaUpdateTaskResponse extends ToolResponse {
|
||||
output: {
|
||||
ts: string
|
||||
gid: string
|
||||
name: string
|
||||
notes: string
|
||||
completed: boolean
|
||||
modified_at: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface AsanaGetProjectsParams {
|
||||
accessToken: string
|
||||
workspace: string
|
||||
}
|
||||
|
||||
export interface AsanaGetProjectsResponse extends ToolResponse {
|
||||
output: {
|
||||
ts: string
|
||||
projects: Array<{
|
||||
gid: string
|
||||
name: string
|
||||
resource_type: string
|
||||
}>
|
||||
}
|
||||
}
|
||||
|
||||
export interface AsanaSearchTasksParams {
|
||||
accessToken: string
|
||||
workspace: string
|
||||
text?: string
|
||||
assignee?: string
|
||||
projects?: string[]
|
||||
completed?: boolean
|
||||
}
|
||||
|
||||
export interface AsanaSearchTasksResponse extends ToolResponse {
|
||||
output: {
|
||||
ts: string
|
||||
tasks: Array<{
|
||||
gid: string
|
||||
resource_type: string
|
||||
resource_subtype: string
|
||||
name: string
|
||||
notes?: string
|
||||
completed: boolean
|
||||
assignee?: {
|
||||
gid: string
|
||||
name: string
|
||||
}
|
||||
created_by?: {
|
||||
gid: string
|
||||
resource_type: string
|
||||
name: string
|
||||
}
|
||||
due_on?: string
|
||||
created_at: string
|
||||
modified_at: string
|
||||
}>
|
||||
next_page?: {
|
||||
offset: string
|
||||
path: string
|
||||
uri: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface AsanaTask {
|
||||
gid: string
|
||||
resource_type: string
|
||||
resource_subtype: string
|
||||
name: string
|
||||
notes?: string
|
||||
completed: boolean
|
||||
assignee?: {
|
||||
gid: string
|
||||
name: string
|
||||
}
|
||||
created_by?: {
|
||||
gid: string
|
||||
resource_type: string
|
||||
name: string
|
||||
}
|
||||
due_on?: string
|
||||
created_at: string
|
||||
modified_at: string
|
||||
}
|
||||
|
||||
interface AsanaProject {
|
||||
gid: string
|
||||
name: string
|
||||
resource_type: string
|
||||
}
|
||||
|
||||
export interface AsanaAddCommentParams {
|
||||
accessToken: string
|
||||
taskGid: string
|
||||
text: string
|
||||
}
|
||||
|
||||
export interface AsanaAddCommentResponse extends ToolResponse {
|
||||
output: {
|
||||
ts: string
|
||||
gid: string
|
||||
text: string
|
||||
created_at: string
|
||||
created_by: {
|
||||
gid: string
|
||||
name: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface AsanaCreateProjectParams {
|
||||
accessToken: string
|
||||
workspace: string
|
||||
name: string
|
||||
notes?: string
|
||||
}
|
||||
|
||||
export interface AsanaProjectRecordResponse extends ToolResponse {
|
||||
output: {
|
||||
ts: string
|
||||
gid: string
|
||||
name: string
|
||||
notes: string
|
||||
archived?: boolean
|
||||
color?: string | null
|
||||
created_at?: string
|
||||
modified_at?: string
|
||||
permalink_url?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface AsanaGetProjectParams {
|
||||
accessToken: string
|
||||
projectGid: string
|
||||
}
|
||||
|
||||
export interface AsanaListWorkspacesParams {
|
||||
accessToken: string
|
||||
}
|
||||
|
||||
export interface AsanaListWorkspacesResponse extends ToolResponse {
|
||||
output: {
|
||||
ts: string
|
||||
workspaces: Array<{
|
||||
gid: string
|
||||
name: string
|
||||
resource_type?: string
|
||||
}>
|
||||
}
|
||||
}
|
||||
|
||||
export interface AsanaCreateSubtaskParams {
|
||||
accessToken: string
|
||||
taskGid: string
|
||||
name: string
|
||||
notes?: string
|
||||
assignee?: string
|
||||
due_on?: string
|
||||
}
|
||||
|
||||
export interface AsanaDeleteTaskParams {
|
||||
accessToken: string
|
||||
taskGid: string
|
||||
}
|
||||
|
||||
export interface AsanaDeleteTaskResponse extends ToolResponse {
|
||||
output: {
|
||||
ts: string
|
||||
gid: string
|
||||
deleted: true
|
||||
}
|
||||
}
|
||||
|
||||
export interface AsanaAddFollowersParams {
|
||||
accessToken: string
|
||||
taskGid: string
|
||||
followers: string[]
|
||||
}
|
||||
|
||||
export interface AsanaAddFollowersResponse extends ToolResponse {
|
||||
output: {
|
||||
ts: string
|
||||
gid: string
|
||||
name: string
|
||||
followers: Array<{
|
||||
gid: string
|
||||
name: string
|
||||
}>
|
||||
}
|
||||
}
|
||||
|
||||
export interface AsanaCreateSectionParams {
|
||||
accessToken: string
|
||||
projectGid: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface AsanaSectionResponse extends ToolResponse {
|
||||
output: {
|
||||
ts: string
|
||||
gid: string
|
||||
name: string
|
||||
created_at?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface AsanaListSectionsParams {
|
||||
accessToken: string
|
||||
projectGid: string
|
||||
}
|
||||
|
||||
export interface AsanaListSectionsResponse extends ToolResponse {
|
||||
output: {
|
||||
ts: string
|
||||
sections: Array<{
|
||||
gid: string
|
||||
name: string
|
||||
resource_type?: string
|
||||
}>
|
||||
}
|
||||
}
|
||||
|
||||
export type AsanaResponse =
|
||||
| AsanaGetTaskResponse
|
||||
| AsanaCreateTaskResponse
|
||||
| AsanaUpdateTaskResponse
|
||||
| AsanaGetProjectsResponse
|
||||
| AsanaSearchTasksResponse
|
||||
| AsanaAddCommentResponse
|
||||
| AsanaProjectRecordResponse
|
||||
| AsanaListWorkspacesResponse
|
||||
| AsanaDeleteTaskResponse
|
||||
| AsanaAddFollowersResponse
|
||||
| AsanaSectionResponse
|
||||
| AsanaListSectionsResponse
|
||||
@@ -0,0 +1,112 @@
|
||||
import type { AsanaUpdateTaskParams, AsanaUpdateTaskResponse } from '@/tools/asana/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const asanaUpdateTaskTool: ToolConfig<AsanaUpdateTaskParams, AsanaUpdateTaskResponse> = {
|
||||
id: 'asana_update_task',
|
||||
name: 'Asana Update Task',
|
||||
description: 'Update an existing task in Asana',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'asana',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'OAuth access token for Asana',
|
||||
},
|
||||
taskGid: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Asana task GID (numeric string) of the task to update',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated name for the task',
|
||||
},
|
||||
notes: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated notes or description for the task',
|
||||
},
|
||||
assignee: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated assignee user GID',
|
||||
},
|
||||
completed: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Mark task as completed or not completed',
|
||||
},
|
||||
due_on: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated due date in YYYY-MM-DD format',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/asana/update-task',
|
||||
method: 'PUT',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
taskGid: params.taskGid,
|
||||
name: params.name,
|
||||
notes: params.notes,
|
||||
assignee: params.assignee,
|
||||
completed: params.completed,
|
||||
due_on: params.due_on,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const responseText = await response.text()
|
||||
|
||||
if (!responseText) {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
ts: new Date().toISOString(),
|
||||
gid: 'unknown',
|
||||
name: 'Task updated successfully',
|
||||
notes: '',
|
||||
completed: false,
|
||||
modified_at: new Date().toISOString(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const data = JSON.parse(responseText)
|
||||
const { success, error, ...output } = data
|
||||
return {
|
||||
success: success ?? true,
|
||||
output,
|
||||
error,
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
ts: { type: 'string', description: 'Timestamp of the response' },
|
||||
gid: { type: 'string', description: 'Task globally unique identifier' },
|
||||
name: { type: 'string', description: 'Task name' },
|
||||
notes: { type: 'string', description: 'Task notes or description' },
|
||||
completed: { type: 'boolean', description: 'Whether the task is completed' },
|
||||
modified_at: { type: 'string', description: 'Task last modified timestamp' },
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user