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,70 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { DevinAppendSessionTagsParams, DevinSessionTagsResponse } from './types'
|
||||
import { normalizeTags } from './utils'
|
||||
|
||||
export const devinAppendSessionTagsTool: ToolConfig<
|
||||
DevinAppendSessionTagsParams,
|
||||
DevinSessionTagsResponse
|
||||
> = {
|
||||
id: 'devin_append_session_tags',
|
||||
name: 'append_session_tags',
|
||||
description: 'Add tags to a Devin session without removing existing tags (max 50 tags total).',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin API key (service user credential starting with cog_)',
|
||||
},
|
||||
orgId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin organization ID (prefixed with org-)',
|
||||
},
|
||||
sessionId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The session ID to add tags to',
|
||||
},
|
||||
tags: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Tags to append to the session (comma-separated string or array of strings)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://api.devin.ai/v3/organizations/${params.orgId.trim()}/sessions/${params.sessionId.trim()}/tags`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
tags: normalizeTags(params.tags),
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
tags: data.tags ?? [],
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
tags: {
|
||||
type: 'json',
|
||||
description: 'Updated list of tags on the session (array of strings)',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { DevinArchiveSessionParams, DevinArchiveSessionResponse } from './types'
|
||||
import { DEVIN_SESSION_OUTPUT_PROPERTIES } from './types'
|
||||
|
||||
export const devinArchiveSessionTool: ToolConfig<
|
||||
DevinArchiveSessionParams,
|
||||
DevinArchiveSessionResponse
|
||||
> = {
|
||||
id: 'devin_archive_session',
|
||||
name: 'archive_session',
|
||||
description:
|
||||
'Archive a Devin session. Archived sessions can still be viewed but cannot be modified or resumed.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin API key (service user credential starting with cog_)',
|
||||
},
|
||||
orgId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin organization ID (prefixed with org-)',
|
||||
},
|
||||
sessionId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The session ID to archive',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://api.devin.ai/v3/organizations/${params.orgId.trim()}/sessions/${params.sessionId.trim()}/archive`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
sessionId: data.session_id ?? null,
|
||||
url: data.url ?? null,
|
||||
status: data.status ?? null,
|
||||
statusDetail: data.status_detail ?? null,
|
||||
title: data.title ?? null,
|
||||
createdAt: data.created_at ?? null,
|
||||
updatedAt: data.updated_at ?? null,
|
||||
acusConsumed: data.acus_consumed ?? null,
|
||||
tags: data.tags ?? [],
|
||||
pullRequests: data.pull_requests ?? [],
|
||||
structuredOutput: data.structured_output ?? null,
|
||||
playbookId: data.playbook_id ?? null,
|
||||
isArchived: data.is_archived ?? false,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
sessionId: DEVIN_SESSION_OUTPUT_PROPERTIES.sessionId,
|
||||
url: DEVIN_SESSION_OUTPUT_PROPERTIES.url,
|
||||
status: DEVIN_SESSION_OUTPUT_PROPERTIES.status,
|
||||
statusDetail: DEVIN_SESSION_OUTPUT_PROPERTIES.statusDetail,
|
||||
title: DEVIN_SESSION_OUTPUT_PROPERTIES.title,
|
||||
createdAt: DEVIN_SESSION_OUTPUT_PROPERTIES.createdAt,
|
||||
updatedAt: DEVIN_SESSION_OUTPUT_PROPERTIES.updatedAt,
|
||||
acusConsumed: DEVIN_SESSION_OUTPUT_PROPERTIES.acusConsumed,
|
||||
tags: DEVIN_SESSION_OUTPUT_PROPERTIES.tags,
|
||||
pullRequests: DEVIN_SESSION_OUTPUT_PROPERTIES.pullRequests,
|
||||
structuredOutput: DEVIN_SESSION_OUTPUT_PROPERTIES.structuredOutput,
|
||||
playbookId: DEVIN_SESSION_OUTPUT_PROPERTIES.playbookId,
|
||||
isArchived: DEVIN_SESSION_OUTPUT_PROPERTIES.isArchived,
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { DevinCreateSessionParams, DevinCreateSessionResponse } from './types'
|
||||
import { DEVIN_SESSION_OUTPUT_PROPERTIES } from './types'
|
||||
import { normalizeTags } from './utils'
|
||||
|
||||
export const devinCreateSessionTool: ToolConfig<
|
||||
DevinCreateSessionParams,
|
||||
DevinCreateSessionResponse
|
||||
> = {
|
||||
id: 'devin_create_session',
|
||||
name: 'create_session',
|
||||
description:
|
||||
'Create a new Devin session with a prompt. Devin will autonomously work on the task described in the prompt.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin API key (service user credential starting with cog_)',
|
||||
},
|
||||
orgId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin organization ID (prefixed with org-)',
|
||||
},
|
||||
prompt: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The task prompt for Devin to work on',
|
||||
},
|
||||
playbookId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Optional playbook ID to guide the session',
|
||||
},
|
||||
maxAcuLimit: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum ACU limit for the session',
|
||||
},
|
||||
tags: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated tags for the session',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.devin.ai/v3/organizations/${params.orgId.trim()}/sessions`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, unknown> = {
|
||||
prompt: params.prompt,
|
||||
}
|
||||
if (params.playbookId) body.playbook_id = params.playbookId
|
||||
if (params.maxAcuLimit != null) {
|
||||
body.max_acu_limit = params.maxAcuLimit
|
||||
}
|
||||
const tags = normalizeTags(params.tags)
|
||||
if (tags.length > 0) body.tags = tags
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
sessionId: data.session_id ?? null,
|
||||
url: data.url ?? null,
|
||||
status: data.status ?? null,
|
||||
statusDetail: data.status_detail ?? null,
|
||||
title: data.title ?? null,
|
||||
createdAt: data.created_at ?? null,
|
||||
updatedAt: data.updated_at ?? null,
|
||||
acusConsumed: data.acus_consumed ?? null,
|
||||
tags: data.tags ?? [],
|
||||
pullRequests: data.pull_requests ?? [],
|
||||
structuredOutput: data.structured_output ?? null,
|
||||
playbookId: data.playbook_id ?? null,
|
||||
isArchived: data.is_archived ?? false,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
sessionId: DEVIN_SESSION_OUTPUT_PROPERTIES.sessionId,
|
||||
url: DEVIN_SESSION_OUTPUT_PROPERTIES.url,
|
||||
status: DEVIN_SESSION_OUTPUT_PROPERTIES.status,
|
||||
statusDetail: DEVIN_SESSION_OUTPUT_PROPERTIES.statusDetail,
|
||||
title: DEVIN_SESSION_OUTPUT_PROPERTIES.title,
|
||||
createdAt: DEVIN_SESSION_OUTPUT_PROPERTIES.createdAt,
|
||||
updatedAt: DEVIN_SESSION_OUTPUT_PROPERTIES.updatedAt,
|
||||
acusConsumed: DEVIN_SESSION_OUTPUT_PROPERTIES.acusConsumed,
|
||||
tags: DEVIN_SESSION_OUTPUT_PROPERTIES.tags,
|
||||
pullRequests: DEVIN_SESSION_OUTPUT_PROPERTIES.pullRequests,
|
||||
structuredOutput: DEVIN_SESSION_OUTPUT_PROPERTIES.structuredOutput,
|
||||
playbookId: DEVIN_SESSION_OUTPUT_PROPERTIES.playbookId,
|
||||
isArchived: DEVIN_SESSION_OUTPUT_PROPERTIES.isArchived,
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { DevinGetSessionParams, DevinGetSessionResponse } from './types'
|
||||
import { DEVIN_SESSION_OUTPUT_PROPERTIES } from './types'
|
||||
|
||||
export const devinGetSessionTool: ToolConfig<DevinGetSessionParams, DevinGetSessionResponse> = {
|
||||
id: 'devin_get_session',
|
||||
name: 'get_session',
|
||||
description:
|
||||
'Retrieve details of an existing Devin session including status, tags, pull requests, and structured output.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin API key (service user credential starting with cog_)',
|
||||
},
|
||||
orgId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin organization ID (prefixed with org-)',
|
||||
},
|
||||
sessionId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The session ID to retrieve',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://api.devin.ai/v3/organizations/${params.orgId.trim()}/sessions/${params.sessionId.trim()}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
sessionId: data.session_id ?? null,
|
||||
url: data.url ?? null,
|
||||
status: data.status ?? null,
|
||||
statusDetail: data.status_detail ?? null,
|
||||
title: data.title ?? null,
|
||||
createdAt: data.created_at ?? null,
|
||||
updatedAt: data.updated_at ?? null,
|
||||
acusConsumed: data.acus_consumed ?? null,
|
||||
tags: data.tags ?? [],
|
||||
pullRequests: data.pull_requests ?? [],
|
||||
structuredOutput: data.structured_output ?? null,
|
||||
playbookId: data.playbook_id ?? null,
|
||||
isArchived: data.is_archived ?? false,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
sessionId: DEVIN_SESSION_OUTPUT_PROPERTIES.sessionId,
|
||||
url: DEVIN_SESSION_OUTPUT_PROPERTIES.url,
|
||||
status: DEVIN_SESSION_OUTPUT_PROPERTIES.status,
|
||||
statusDetail: DEVIN_SESSION_OUTPUT_PROPERTIES.statusDetail,
|
||||
title: DEVIN_SESSION_OUTPUT_PROPERTIES.title,
|
||||
createdAt: DEVIN_SESSION_OUTPUT_PROPERTIES.createdAt,
|
||||
updatedAt: DEVIN_SESSION_OUTPUT_PROPERTIES.updatedAt,
|
||||
acusConsumed: DEVIN_SESSION_OUTPUT_PROPERTIES.acusConsumed,
|
||||
tags: DEVIN_SESSION_OUTPUT_PROPERTIES.tags,
|
||||
pullRequests: DEVIN_SESSION_OUTPUT_PROPERTIES.pullRequests,
|
||||
structuredOutput: DEVIN_SESSION_OUTPUT_PROPERTIES.structuredOutput,
|
||||
playbookId: DEVIN_SESSION_OUTPUT_PROPERTIES.playbookId,
|
||||
isArchived: DEVIN_SESSION_OUTPUT_PROPERTIES.isArchived,
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { DevinGetSessionTagsParams, DevinSessionTagsResponse } from './types'
|
||||
|
||||
export const devinGetSessionTagsTool: ToolConfig<
|
||||
DevinGetSessionTagsParams,
|
||||
DevinSessionTagsResponse
|
||||
> = {
|
||||
id: 'devin_get_session_tags',
|
||||
name: 'get_session_tags',
|
||||
description: 'Retrieve the tags currently applied to a Devin session.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin API key (service user credential starting with cog_)',
|
||||
},
|
||||
orgId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin organization ID (prefixed with org-)',
|
||||
},
|
||||
sessionId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The session ID to retrieve tags for',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://api.devin.ai/v3/organizations/${params.orgId.trim()}/sessions/${params.sessionId.trim()}/tags`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
tags: data.tags ?? [],
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
tags: {
|
||||
type: 'json',
|
||||
description: 'Tags applied to the session (array of strings)',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
export { devinAppendSessionTagsTool } from './append_session_tags'
|
||||
export { devinArchiveSessionTool } from './archive_session'
|
||||
export { devinCreateSessionTool } from './create_session'
|
||||
export { devinGetSessionTool } from './get_session'
|
||||
export { devinGetSessionTagsTool } from './get_session_tags'
|
||||
export { devinListSessionAttachmentsTool } from './list_session_attachments'
|
||||
export { devinListSessionMessagesTool } from './list_session_messages'
|
||||
export { devinListSessionsTool } from './list_sessions'
|
||||
export { devinReplaceSessionTagsTool } from './replace_session_tags'
|
||||
export { devinSendMessageTool } from './send_message'
|
||||
export { devinTerminateSessionTool } from './terminate_session'
|
||||
@@ -0,0 +1,74 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type {
|
||||
DevinListSessionAttachmentsParams,
|
||||
DevinListSessionAttachmentsResponse,
|
||||
} from './types'
|
||||
import { DEVIN_SESSION_ATTACHMENT_PROPERTIES } from './types'
|
||||
|
||||
export const devinListSessionAttachmentsTool: ToolConfig<
|
||||
DevinListSessionAttachmentsParams,
|
||||
DevinListSessionAttachmentsResponse
|
||||
> = {
|
||||
id: 'devin_list_session_attachments',
|
||||
name: 'list_session_attachments',
|
||||
description: 'List the files uploaded to or produced by a Devin session.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin API key (service user credential starting with cog_)',
|
||||
},
|
||||
orgId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin organization ID (prefixed with org-)',
|
||||
},
|
||||
sessionId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The session ID to list attachments for',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://api.devin.ai/v3/organizations/${params.orgId.trim()}/sessions/${params.sessionId.trim()}/attachments`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
const items = Array.isArray(data) ? data : (data.items ?? [])
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
attachments: items.map((item: Record<string, unknown>) => ({
|
||||
attachmentId: item.attachment_id ?? null,
|
||||
name: item.name ?? null,
|
||||
url: item.url ?? null,
|
||||
source: item.source ?? null,
|
||||
contentType: item.content_type ?? null,
|
||||
})),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
attachments: {
|
||||
type: 'array',
|
||||
description: 'Attachments associated with the session',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: DEVIN_SESSION_ATTACHMENT_PROPERTIES,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { DevinListSessionMessagesParams, DevinListSessionMessagesResponse } from './types'
|
||||
import { DEVIN_SESSION_MESSAGE_PROPERTIES } from './types'
|
||||
|
||||
export const devinListSessionMessagesTool: ToolConfig<
|
||||
DevinListSessionMessagesParams,
|
||||
DevinListSessionMessagesResponse
|
||||
> = {
|
||||
id: 'devin_list_session_messages',
|
||||
name: 'list_session_messages',
|
||||
description:
|
||||
'List the messages exchanged in a Devin session, including messages from both the user and Devin.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin API key (service user credential starting with cog_)',
|
||||
},
|
||||
orgId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin organization ID (prefixed with org-)',
|
||||
},
|
||||
sessionId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The session ID to list messages for',
|
||||
},
|
||||
limit: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of messages to return (1-200, default: 100)',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination cursor (endCursor from a previous response) to fetch the next page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const searchParams = new URLSearchParams()
|
||||
if (params.limit) searchParams.set('first', String(params.limit))
|
||||
if (params.after) searchParams.set('after', params.after.trim())
|
||||
const qs = searchParams.toString()
|
||||
return `https://api.devin.ai/v3/organizations/${params.orgId.trim()}/sessions/${params.sessionId.trim()}/messages${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
const items = data.items ?? []
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
messages: items.map((item: Record<string, unknown>) => ({
|
||||
eventId: item.event_id ?? null,
|
||||
source: item.source ?? null,
|
||||
message: item.message ?? null,
|
||||
createdAt: item.created_at ?? null,
|
||||
})),
|
||||
endCursor: data.end_cursor ?? null,
|
||||
hasNextPage: data.has_next_page ?? false,
|
||||
total: data.total ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
messages: {
|
||||
type: 'array',
|
||||
description: 'Messages exchanged in the session',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: DEVIN_SESSION_MESSAGE_PROPERTIES,
|
||||
},
|
||||
},
|
||||
endCursor: {
|
||||
type: 'string',
|
||||
description: 'Pagination cursor for the next page, or null if last page',
|
||||
optional: true,
|
||||
},
|
||||
hasNextPage: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more messages are available',
|
||||
},
|
||||
total: {
|
||||
type: 'number',
|
||||
description: 'Total number of messages, if provided',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { DevinListSessionsParams, DevinListSessionsResponse } from './types'
|
||||
import { DEVIN_SESSION_LIST_ITEM_PROPERTIES } from './types'
|
||||
|
||||
export const devinListSessionsTool: ToolConfig<DevinListSessionsParams, DevinListSessionsResponse> =
|
||||
{
|
||||
id: 'devin_list_sessions',
|
||||
name: 'list_sessions',
|
||||
description: 'List Devin sessions in the organization. Returns up to 100 sessions by default.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin API key (service user credential starting with cog_)',
|
||||
},
|
||||
orgId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin organization ID (prefixed with org-)',
|
||||
},
|
||||
limit: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of sessions to return (1-200, default: 100)',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Pagination cursor (endCursor from a previous response) to fetch the next page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const searchParams = new URLSearchParams()
|
||||
if (params.limit) searchParams.set('first', String(params.limit))
|
||||
if (params.after) searchParams.set('after', params.after.trim())
|
||||
const qs = searchParams.toString()
|
||||
return `https://api.devin.ai/v3/organizations/${params.orgId.trim()}/sessions${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
const items = data.items ?? []
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
sessions: items.map((item: Record<string, unknown>) => ({
|
||||
sessionId: item.session_id ?? null,
|
||||
url: item.url ?? null,
|
||||
status: item.status ?? null,
|
||||
statusDetail: item.status_detail ?? null,
|
||||
title: item.title ?? null,
|
||||
createdAt: item.created_at ?? null,
|
||||
updatedAt: item.updated_at ?? null,
|
||||
tags: item.tags ?? [],
|
||||
acusConsumed: item.acus_consumed ?? null,
|
||||
pullRequests: item.pull_requests ?? [],
|
||||
playbookId: item.playbook_id ?? null,
|
||||
isArchived: item.is_archived ?? false,
|
||||
})),
|
||||
endCursor: data.end_cursor ?? null,
|
||||
hasNextPage: data.has_next_page ?? false,
|
||||
total: data.total ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
sessions: {
|
||||
type: 'array',
|
||||
description: 'List of Devin sessions',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: DEVIN_SESSION_LIST_ITEM_PROPERTIES,
|
||||
},
|
||||
},
|
||||
endCursor: {
|
||||
type: 'string',
|
||||
description: 'Pagination cursor for the next page, or null if last page',
|
||||
optional: true,
|
||||
},
|
||||
hasNextPage: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more sessions are available',
|
||||
},
|
||||
total: {
|
||||
type: 'number',
|
||||
description: 'Total number of sessions, if provided',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { DevinReplaceSessionTagsParams, DevinSessionTagsResponse } from './types'
|
||||
import { normalizeTags } from './utils'
|
||||
|
||||
export const devinReplaceSessionTagsTool: ToolConfig<
|
||||
DevinReplaceSessionTagsParams,
|
||||
DevinSessionTagsResponse
|
||||
> = {
|
||||
id: 'devin_replace_session_tags',
|
||||
name: 'replace_session_tags',
|
||||
description: 'Replace all tags on a Devin session with a new set of tags (max 50 tags).',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin API key (service user credential starting with cog_)',
|
||||
},
|
||||
orgId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin organization ID (prefixed with org-)',
|
||||
},
|
||||
sessionId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The session ID to replace tags on',
|
||||
},
|
||||
tags: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Tags that will overwrite the existing tags (comma-separated string or array of strings)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://api.devin.ai/v3/organizations/${params.orgId.trim()}/sessions/${params.sessionId.trim()}/tags`,
|
||||
method: 'PUT',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
tags: normalizeTags(params.tags),
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
tags: data.tags ?? [],
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
tags: {
|
||||
type: 'json',
|
||||
description: 'Updated list of tags on the session (array of strings)',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { DevinSendMessageParams, DevinSendMessageResponse } from './types'
|
||||
import { DEVIN_SESSION_OUTPUT_PROPERTIES } from './types'
|
||||
|
||||
export const devinSendMessageTool: ToolConfig<DevinSendMessageParams, DevinSendMessageResponse> = {
|
||||
id: 'devin_send_message',
|
||||
name: 'send_message',
|
||||
description:
|
||||
'Send a message to a Devin session. If the session is suspended, it will be automatically resumed. Returns the updated session state.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin API key (service user credential starting with cog_)',
|
||||
},
|
||||
orgId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin organization ID (prefixed with org-)',
|
||||
},
|
||||
sessionId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The session ID to send the message to',
|
||||
},
|
||||
message: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The message to send to Devin',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://api.devin.ai/v3/organizations/${params.orgId.trim()}/sessions/${params.sessionId.trim()}/messages`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
message: params.message,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
sessionId: data.session_id ?? null,
|
||||
url: data.url ?? null,
|
||||
status: data.status ?? null,
|
||||
statusDetail: data.status_detail ?? null,
|
||||
title: data.title ?? null,
|
||||
createdAt: data.created_at ?? null,
|
||||
updatedAt: data.updated_at ?? null,
|
||||
acusConsumed: data.acus_consumed ?? null,
|
||||
tags: data.tags ?? [],
|
||||
pullRequests: data.pull_requests ?? [],
|
||||
structuredOutput: data.structured_output ?? null,
|
||||
playbookId: data.playbook_id ?? null,
|
||||
isArchived: data.is_archived ?? false,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
sessionId: DEVIN_SESSION_OUTPUT_PROPERTIES.sessionId,
|
||||
url: DEVIN_SESSION_OUTPUT_PROPERTIES.url,
|
||||
status: DEVIN_SESSION_OUTPUT_PROPERTIES.status,
|
||||
statusDetail: DEVIN_SESSION_OUTPUT_PROPERTIES.statusDetail,
|
||||
title: DEVIN_SESSION_OUTPUT_PROPERTIES.title,
|
||||
createdAt: DEVIN_SESSION_OUTPUT_PROPERTIES.createdAt,
|
||||
updatedAt: DEVIN_SESSION_OUTPUT_PROPERTIES.updatedAt,
|
||||
acusConsumed: DEVIN_SESSION_OUTPUT_PROPERTIES.acusConsumed,
|
||||
tags: DEVIN_SESSION_OUTPUT_PROPERTIES.tags,
|
||||
pullRequests: DEVIN_SESSION_OUTPUT_PROPERTIES.pullRequests,
|
||||
structuredOutput: DEVIN_SESSION_OUTPUT_PROPERTIES.structuredOutput,
|
||||
playbookId: DEVIN_SESSION_OUTPUT_PROPERTIES.playbookId,
|
||||
isArchived: DEVIN_SESSION_OUTPUT_PROPERTIES.isArchived,
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { DevinTerminateSessionParams, DevinTerminateSessionResponse } from './types'
|
||||
import { DEVIN_SESSION_OUTPUT_PROPERTIES } from './types'
|
||||
|
||||
export const devinTerminateSessionTool: ToolConfig<
|
||||
DevinTerminateSessionParams,
|
||||
DevinTerminateSessionResponse
|
||||
> = {
|
||||
id: 'devin_terminate_session',
|
||||
name: 'terminate_session',
|
||||
description:
|
||||
'Terminate a Devin session. Optionally archive the session instead of permanently terminating it.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin API key (service user credential starting with cog_)',
|
||||
},
|
||||
orgId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Devin organization ID (prefixed with org-)',
|
||||
},
|
||||
sessionId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The session ID to terminate',
|
||||
},
|
||||
archive: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Archive the session instead of permanently terminating it (default: false)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const searchParams = new URLSearchParams()
|
||||
if (params.archive) searchParams.set('archive', 'true')
|
||||
const qs = searchParams.toString()
|
||||
return `https://api.devin.ai/v3/organizations/${params.orgId.trim()}/sessions/${params.sessionId.trim()}${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'DELETE',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
sessionId: data.session_id ?? null,
|
||||
url: data.url ?? null,
|
||||
status: data.status ?? null,
|
||||
statusDetail: data.status_detail ?? null,
|
||||
title: data.title ?? null,
|
||||
createdAt: data.created_at ?? null,
|
||||
updatedAt: data.updated_at ?? null,
|
||||
acusConsumed: data.acus_consumed ?? null,
|
||||
tags: data.tags ?? [],
|
||||
pullRequests: data.pull_requests ?? [],
|
||||
structuredOutput: data.structured_output ?? null,
|
||||
playbookId: data.playbook_id ?? null,
|
||||
isArchived: data.is_archived ?? false,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
sessionId: DEVIN_SESSION_OUTPUT_PROPERTIES.sessionId,
|
||||
url: DEVIN_SESSION_OUTPUT_PROPERTIES.url,
|
||||
status: DEVIN_SESSION_OUTPUT_PROPERTIES.status,
|
||||
statusDetail: DEVIN_SESSION_OUTPUT_PROPERTIES.statusDetail,
|
||||
title: DEVIN_SESSION_OUTPUT_PROPERTIES.title,
|
||||
createdAt: DEVIN_SESSION_OUTPUT_PROPERTIES.createdAt,
|
||||
updatedAt: DEVIN_SESSION_OUTPUT_PROPERTIES.updatedAt,
|
||||
acusConsumed: DEVIN_SESSION_OUTPUT_PROPERTIES.acusConsumed,
|
||||
tags: DEVIN_SESSION_OUTPUT_PROPERTIES.tags,
|
||||
pullRequests: DEVIN_SESSION_OUTPUT_PROPERTIES.pullRequests,
|
||||
structuredOutput: DEVIN_SESSION_OUTPUT_PROPERTIES.structuredOutput,
|
||||
playbookId: DEVIN_SESSION_OUTPUT_PROPERTIES.playbookId,
|
||||
isArchived: DEVIN_SESSION_OUTPUT_PROPERTIES.isArchived,
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
import type { OutputProperty, ToolResponse } from '@/tools/types'
|
||||
|
||||
export interface DevinCreateSessionParams {
|
||||
apiKey: string
|
||||
orgId: string
|
||||
prompt: string
|
||||
playbookId?: string
|
||||
maxAcuLimit?: number
|
||||
tags?: string | string[]
|
||||
}
|
||||
|
||||
export interface DevinGetSessionParams {
|
||||
apiKey: string
|
||||
orgId: string
|
||||
sessionId: string
|
||||
}
|
||||
|
||||
export interface DevinListSessionsParams {
|
||||
apiKey: string
|
||||
orgId: string
|
||||
limit?: number
|
||||
after?: string
|
||||
}
|
||||
|
||||
export interface DevinSendMessageParams {
|
||||
apiKey: string
|
||||
orgId: string
|
||||
sessionId: string
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface DevinListSessionMessagesParams {
|
||||
apiKey: string
|
||||
orgId: string
|
||||
sessionId: string
|
||||
limit?: number
|
||||
after?: string
|
||||
}
|
||||
|
||||
export interface DevinListSessionAttachmentsParams {
|
||||
apiKey: string
|
||||
orgId: string
|
||||
sessionId: string
|
||||
}
|
||||
|
||||
export interface DevinGetSessionTagsParams {
|
||||
apiKey: string
|
||||
orgId: string
|
||||
sessionId: string
|
||||
}
|
||||
|
||||
export interface DevinAppendSessionTagsParams {
|
||||
apiKey: string
|
||||
orgId: string
|
||||
sessionId: string
|
||||
tags: string | string[]
|
||||
}
|
||||
|
||||
export interface DevinReplaceSessionTagsParams {
|
||||
apiKey: string
|
||||
orgId: string
|
||||
sessionId: string
|
||||
tags: string | string[]
|
||||
}
|
||||
|
||||
export interface DevinArchiveSessionParams {
|
||||
apiKey: string
|
||||
orgId: string
|
||||
sessionId: string
|
||||
}
|
||||
|
||||
export interface DevinTerminateSessionParams {
|
||||
apiKey: string
|
||||
orgId: string
|
||||
sessionId: string
|
||||
archive?: boolean
|
||||
}
|
||||
|
||||
export const DEVIN_SESSION_OUTPUT_PROPERTIES = {
|
||||
sessionId: {
|
||||
type: 'string',
|
||||
description: 'Unique identifier for the session',
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
description: 'URL to view the session in the Devin UI',
|
||||
},
|
||||
status: {
|
||||
type: 'string',
|
||||
description: 'Session status (new, claimed, running, exit, error, suspended, resuming)',
|
||||
},
|
||||
statusDetail: {
|
||||
type: 'string',
|
||||
description:
|
||||
'Detailed status (working, waiting_for_user, waiting_for_approval, finished, inactivity, etc.)',
|
||||
optional: true,
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
description: 'Session title',
|
||||
optional: true,
|
||||
},
|
||||
createdAt: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when the session was created',
|
||||
optional: true,
|
||||
},
|
||||
updatedAt: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when the session was last updated',
|
||||
optional: true,
|
||||
},
|
||||
acusConsumed: {
|
||||
type: 'number',
|
||||
description: 'ACUs consumed by the session',
|
||||
optional: true,
|
||||
},
|
||||
tags: {
|
||||
type: 'json',
|
||||
description: 'Tags associated with the session (array of strings)',
|
||||
},
|
||||
pullRequests: {
|
||||
type: 'json',
|
||||
description: 'Pull requests created during the session ([{pr_url, pr_state}])',
|
||||
},
|
||||
structuredOutput: {
|
||||
type: 'json',
|
||||
description: 'Structured output from the session',
|
||||
optional: true,
|
||||
},
|
||||
playbookId: {
|
||||
type: 'string',
|
||||
description: 'Associated playbook ID',
|
||||
optional: true,
|
||||
},
|
||||
isArchived: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the session is archived',
|
||||
optional: true,
|
||||
},
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
export const DEVIN_SESSION_LIST_ITEM_PROPERTIES = {
|
||||
sessionId: {
|
||||
type: 'string',
|
||||
description: 'Unique identifier for the session',
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
description: 'URL to view the session',
|
||||
},
|
||||
status: {
|
||||
type: 'string',
|
||||
description: 'Session status',
|
||||
},
|
||||
statusDetail: {
|
||||
type: 'string',
|
||||
description: 'Detailed status',
|
||||
optional: true,
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
description: 'Session title',
|
||||
optional: true,
|
||||
},
|
||||
createdAt: {
|
||||
type: 'number',
|
||||
description: 'Creation timestamp (Unix)',
|
||||
optional: true,
|
||||
},
|
||||
updatedAt: {
|
||||
type: 'number',
|
||||
description: 'Last updated timestamp (Unix)',
|
||||
optional: true,
|
||||
},
|
||||
tags: {
|
||||
type: 'json',
|
||||
description: 'Session tags (array of strings)',
|
||||
},
|
||||
acusConsumed: {
|
||||
type: 'number',
|
||||
description: 'ACUs consumed by the session',
|
||||
optional: true,
|
||||
},
|
||||
pullRequests: {
|
||||
type: 'json',
|
||||
description: 'Pull requests created during the session ([{pr_url, pr_state}])',
|
||||
},
|
||||
playbookId: {
|
||||
type: 'string',
|
||||
description: 'Associated playbook ID',
|
||||
optional: true,
|
||||
},
|
||||
isArchived: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the session is archived',
|
||||
optional: true,
|
||||
},
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
export const DEVIN_SESSION_MESSAGE_PROPERTIES = {
|
||||
eventId: {
|
||||
type: 'string',
|
||||
description: 'Unique identifier for the message event',
|
||||
},
|
||||
source: {
|
||||
type: 'string',
|
||||
description: 'Origin of the message (devin or user)',
|
||||
},
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'The message content',
|
||||
},
|
||||
createdAt: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when the message was created',
|
||||
optional: true,
|
||||
},
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
export const DEVIN_SESSION_ATTACHMENT_PROPERTIES = {
|
||||
attachmentId: {
|
||||
type: 'string',
|
||||
description: 'Unique identifier for the attachment',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Attachment file name',
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
description: 'URL to download the attachment',
|
||||
},
|
||||
source: {
|
||||
type: 'string',
|
||||
description: 'Origin of the attachment (devin or user)',
|
||||
},
|
||||
contentType: {
|
||||
type: 'string',
|
||||
description: 'MIME type of the attachment',
|
||||
optional: true,
|
||||
},
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
interface DevinSessionOutput {
|
||||
sessionId: string
|
||||
url: string
|
||||
status: string
|
||||
statusDetail: string | null
|
||||
title: string | null
|
||||
createdAt: number | null
|
||||
updatedAt: number | null
|
||||
acusConsumed: number | null
|
||||
tags: string[]
|
||||
pullRequests: Array<{ pr_url: string; pr_state: string | null }>
|
||||
structuredOutput: Record<string, unknown> | null
|
||||
playbookId: string | null
|
||||
isArchived: boolean
|
||||
}
|
||||
|
||||
export interface DevinCreateSessionResponse extends ToolResponse {
|
||||
output: DevinSessionOutput
|
||||
}
|
||||
|
||||
export interface DevinGetSessionResponse extends ToolResponse {
|
||||
output: DevinSessionOutput
|
||||
}
|
||||
|
||||
export interface DevinListSessionsResponse extends ToolResponse {
|
||||
output: {
|
||||
sessions: Array<{
|
||||
sessionId: string
|
||||
url: string
|
||||
status: string
|
||||
statusDetail: string | null
|
||||
title: string | null
|
||||
createdAt: number | null
|
||||
updatedAt: number | null
|
||||
tags: string[]
|
||||
acusConsumed: number | null
|
||||
pullRequests: Array<{ pr_url: string; pr_state: string | null }>
|
||||
playbookId: string | null
|
||||
isArchived: boolean
|
||||
}>
|
||||
endCursor: string | null
|
||||
hasNextPage: boolean
|
||||
total: number | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface DevinSendMessageResponse extends ToolResponse {
|
||||
output: DevinSessionOutput
|
||||
}
|
||||
|
||||
export interface DevinListSessionMessagesResponse extends ToolResponse {
|
||||
output: {
|
||||
messages: Array<{
|
||||
eventId: string
|
||||
source: string
|
||||
message: string
|
||||
createdAt: number | null
|
||||
}>
|
||||
endCursor: string | null
|
||||
hasNextPage: boolean
|
||||
total: number | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface DevinListSessionAttachmentsResponse extends ToolResponse {
|
||||
output: {
|
||||
attachments: Array<{
|
||||
attachmentId: string
|
||||
name: string
|
||||
url: string
|
||||
source: string
|
||||
contentType: string | null
|
||||
}>
|
||||
}
|
||||
}
|
||||
|
||||
export interface DevinSessionTagsResponse extends ToolResponse {
|
||||
output: {
|
||||
tags: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export interface DevinArchiveSessionResponse extends ToolResponse {
|
||||
output: DevinSessionOutput
|
||||
}
|
||||
|
||||
export interface DevinTerminateSessionResponse extends ToolResponse {
|
||||
output: DevinSessionOutput
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Normalize a tags input into a clean string array.
|
||||
*
|
||||
* Tags can arrive either as a comma-separated string (typed into the block's
|
||||
* text input) or as a string array (when wired from another block's JSON
|
||||
* output, e.g. the tags returned by a get/append/replace tags operation).
|
||||
*/
|
||||
export function normalizeTags(input: string | string[] | undefined | null): string[] {
|
||||
if (Array.isArray(input)) {
|
||||
return input.map((tag) => String(tag).trim()).filter(Boolean)
|
||||
}
|
||||
if (typeof input === 'string') {
|
||||
return input
|
||||
.split(',')
|
||||
.map((tag) => tag.trim())
|
||||
.filter(Boolean)
|
||||
}
|
||||
return []
|
||||
}
|
||||
Reference in New Issue
Block a user