chore: import upstream snapshot with attribution
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
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

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
import type { GammaCheckStatusParams, GammaCheckStatusResponse } from '@/tools/gamma/types'
import type { ToolConfig } from '@/tools/types'
export const checkStatusTool: ToolConfig<GammaCheckStatusParams, GammaCheckStatusResponse> = {
id: 'gamma_check_status',
name: 'Gamma Check Status',
description:
'Check the status of a Gamma generation job. Returns the gamma URL when completed, or error details if failed.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Gamma API key',
},
generationId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The generation ID returned by the Generate or Generate from Template tool',
},
},
request: {
url: (params) => `https://public-api.gamma.app/v1.0/generations/${params.generationId}`,
method: 'GET',
headers: (params) => ({
'X-API-KEY': params.apiKey,
}),
},
transformResponse: async (response: Response): Promise<GammaCheckStatusResponse> => {
const data = await response.json()
const output: GammaCheckStatusResponse['output'] = {
generationId: data.generationId ?? '',
status: data.status ?? 'pending',
gammaUrl: data.gammaUrl ?? null,
}
if (data.credits) {
output.credits = {
deducted: data.credits.deducted ?? null,
remaining: data.credits.remaining ?? null,
}
}
if (data.error) {
output.error = {
message: data.error.message ?? null,
statusCode: data.error.statusCode ?? null,
}
}
return { success: true, output }
},
outputs: {
generationId: {
type: 'string',
description: 'The generation ID that was checked',
},
status: {
type: 'string',
description: 'Generation status: pending, completed, or failed',
},
gammaUrl: {
type: 'string',
description: 'URL of the generated gamma (only present when status is completed)',
optional: true,
},
credits: {
type: 'object',
description: 'Credit usage information (only present when status is completed)',
optional: true,
properties: {
deducted: {
type: 'number',
description: 'Number of credits deducted for this generation',
optional: true,
},
remaining: {
type: 'number',
description: 'Remaining credits in the account',
optional: true,
},
},
},
error: {
type: 'object',
description: 'Error details (only present when status is failed)',
optional: true,
properties: {
message: {
type: 'string',
description: 'Human-readable error message',
optional: true,
},
statusCode: {
type: 'number',
description: 'HTTP status code of the error',
optional: true,
},
},
},
},
}
+189
View File
@@ -0,0 +1,189 @@
import type { GammaGenerateParams, GammaGenerateResponse } from '@/tools/gamma/types'
import type { ToolConfig } from '@/tools/types'
export const generateTool: ToolConfig<GammaGenerateParams, GammaGenerateResponse> = {
id: 'gamma_generate',
name: 'Gamma Generate',
description:
'Generate a new Gamma presentation, document, webpage, or social post from text input.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Gamma API key',
},
inputText: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Text and image URLs used to generate your gamma (1-100,000 tokens)',
},
textMode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description:
'How to handle input text: generate (AI expands), condense (AI summarizes), or preserve (keep as-is)',
},
format: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Output format: presentation, document, webpage, or social (default: presentation)',
},
themeId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Custom Gamma workspace theme ID (use List Themes to find available themes)',
},
numCards: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of cards/slides to generate (1-60 for Pro, 1-75 for Ultra; default: 10)',
},
cardSplit: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'How to split content into cards: auto or inputTextBreaks (default: auto)',
},
cardDimensions: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Card aspect ratio. Presentation: fluid, 16x9, 4x3. Document: fluid, pageless, letter, a4. Social: 1x1, 4x5, 9x16',
},
additionalInstructions: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Additional instructions for the AI generation (max 2000 chars)',
},
exportAs: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Automatically export the generated gamma as pdf or pptx',
},
folderIds: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated folder IDs to store the generated gamma in',
},
textAmount: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Amount of text per card: brief, medium, detailed, or extensive',
},
textTone: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Tone of the generated text, e.g. "professional", "casual" (max 500 chars)',
},
textAudience: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Target audience for the generated text, e.g. "executives", "students" (max 500 chars)',
},
textLanguage: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Language code for the generated text (default: en)',
},
imageSource: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Where to source images: aiGenerated, pictographic, unsplash, webAllImages, webFreeToUse, webFreeToUseCommercially, giphy, placeholder, or noImages',
},
imageModel: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'AI image generation model to use when imageSource is aiGenerated',
},
imageStyle: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Style directive for AI-generated images, e.g. "watercolor", "photorealistic" (max 500 chars)',
},
},
request: {
url: 'https://public-api.gamma.app/v1.0/generations',
method: 'POST',
headers: (params) => ({
'Content-Type': 'application/json',
'X-API-KEY': params.apiKey,
}),
body: (params) => {
const body: Record<string, unknown> = {
inputText: params.inputText,
textMode: params.textMode,
}
if (params.format) body.format = params.format
if (params.themeId) body.themeId = params.themeId
if (params.numCards) body.numCards = params.numCards
if (params.cardSplit) body.cardSplit = params.cardSplit
if (params.additionalInstructions) body.additionalInstructions = params.additionalInstructions
if (params.exportAs) body.exportAs = params.exportAs
if (params.folderIds) {
body.folderIds = params.folderIds.split(',').map((id: string) => id.trim())
}
const textOptions: Record<string, unknown> = {}
if (params.textAmount) textOptions.amount = params.textAmount
if (params.textTone) textOptions.tone = params.textTone
if (params.textAudience) textOptions.audience = params.textAudience
if (params.textLanguage) textOptions.language = params.textLanguage
if (Object.keys(textOptions).length > 0) body.textOptions = textOptions
const imageOptions: Record<string, unknown> = {}
if (params.imageSource) imageOptions.source = params.imageSource
if (params.imageModel) imageOptions.model = params.imageModel
if (params.imageStyle) imageOptions.style = params.imageStyle
if (Object.keys(imageOptions).length > 0) body.imageOptions = imageOptions
const cardOptions: Record<string, unknown> = {}
if (params.cardDimensions) cardOptions.dimensions = params.cardDimensions
if (Object.keys(cardOptions).length > 0) body.cardOptions = cardOptions
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: {
generationId: data.generationId ?? '',
},
}
},
outputs: {
generationId: {
type: 'string',
description: 'The ID of the generation job. Use with Check Status to poll for completion.',
},
},
}
@@ -0,0 +1,113 @@
import type {
GammaGenerateFromTemplateParams,
GammaGenerateFromTemplateResponse,
} from '@/tools/gamma/types'
import type { ToolConfig } from '@/tools/types'
export const generateFromTemplateTool: ToolConfig<
GammaGenerateFromTemplateParams,
GammaGenerateFromTemplateResponse
> = {
id: 'gamma_generate_from_template',
name: 'Gamma Generate from Template',
description: 'Generate a new Gamma by adapting an existing template with a prompt.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Gamma API key',
},
gammaId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the template gamma to adapt',
},
prompt: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Instructions for how to adapt the template (1-100,000 tokens)',
},
themeId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Custom Gamma workspace theme ID to apply',
},
exportAs: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Automatically export the generated gamma as pdf or pptx',
},
folderIds: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated folder IDs to store the generated gamma in',
},
imageModel: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'AI image generation model to use when imageSource is aiGenerated',
},
imageStyle: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Style directive for AI-generated images, e.g. "watercolor", "photorealistic" (max 500 chars)',
},
},
request: {
url: 'https://public-api.gamma.app/v1.0/generations/from-template',
method: 'POST',
headers: (params) => ({
'Content-Type': 'application/json',
'X-API-KEY': params.apiKey,
}),
body: (params) => {
const body: Record<string, unknown> = {
gammaId: params.gammaId,
prompt: params.prompt,
}
if (params.themeId) body.themeId = params.themeId
if (params.exportAs) body.exportAs = params.exportAs
if (params.folderIds) {
body.folderIds = params.folderIds.split(',').map((id: string) => id.trim())
}
const imageOptions: Record<string, unknown> = {}
if (params.imageModel) imageOptions.model = params.imageModel
if (params.imageStyle) imageOptions.style = params.imageStyle
if (Object.keys(imageOptions).length > 0) body.imageOptions = imageOptions
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: {
generationId: data.generationId ?? '',
},
}
},
outputs: {
generationId: {
type: 'string',
description: 'The ID of the generation job. Use with Check Status to poll for completion.',
},
},
}
+11
View File
@@ -0,0 +1,11 @@
import { checkStatusTool } from '@/tools/gamma/check_status'
import { generateTool } from '@/tools/gamma/generate'
import { generateFromTemplateTool } from '@/tools/gamma/generate_from_template'
import { listFoldersTool } from '@/tools/gamma/list_folders'
import { listThemesTool } from '@/tools/gamma/list_themes'
export const gammaGenerateTool = generateTool
export const gammaGenerateFromTemplateTool = generateFromTemplateTool
export const gammaCheckStatusTool = checkStatusTool
export const gammaListThemesTool = listThemesTool
export const gammaListFoldersTool = listFoldersTool
+91
View File
@@ -0,0 +1,91 @@
import type { GammaListFoldersParams, GammaListFoldersResponse } from '@/tools/gamma/types'
import type { ToolConfig } from '@/tools/types'
export const listFoldersTool: ToolConfig<GammaListFoldersParams, GammaListFoldersResponse> = {
id: 'gamma_list_folders',
name: 'Gamma List Folders',
description:
'List available folders in your Gamma workspace. Returns folder IDs and names for organizing generated content.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Gamma API key',
},
query: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Search query to filter folders by name (case-sensitive)',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of folders to return per page (max 50)',
},
after: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor from a previous response (nextCursor) to fetch the next page',
},
},
request: {
url: (params) => {
const url = new URL('https://public-api.gamma.app/v1.0/folders')
if (params.query) url.searchParams.append('query', params.query)
if (params.limit) url.searchParams.append('limit', String(params.limit))
if (params.after) url.searchParams.append('after', params.after)
return url.toString()
},
method: 'GET',
headers: (params) => ({
'X-API-KEY': params.apiKey,
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const items = Array.isArray(data.data) ? data.data : Array.isArray(data) ? data : []
return {
success: true,
output: {
folders: items.map((folder: { id?: string; name?: string }) => ({
id: folder.id ?? '',
name: folder.name ?? '',
})),
hasMore: data.hasMore ?? false,
nextCursor: data.nextCursor ?? null,
},
}
},
outputs: {
folders: {
type: 'array',
description: 'List of available folders',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Folder ID (use with folderIds parameter)' },
name: { type: 'string', description: 'Folder display name' },
},
},
},
hasMore: {
type: 'boolean',
description: 'Whether more results are available on the next page',
},
nextCursor: {
type: 'string',
description: 'Pagination cursor to pass as the after parameter for the next page',
optional: true,
},
},
}
+113
View File
@@ -0,0 +1,113 @@
import type { GammaListThemesParams, GammaListThemesResponse } from '@/tools/gamma/types'
import type { ToolConfig } from '@/tools/types'
export const listThemesTool: ToolConfig<GammaListThemesParams, GammaListThemesResponse> = {
id: 'gamma_list_themes',
name: 'Gamma List Themes',
description:
'List available themes in your Gamma workspace. Returns theme IDs, names, and keywords for styling.',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Gamma API key',
},
query: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Search query to filter themes by name (case-insensitive)',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of themes to return per page (max 50)',
},
after: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor from a previous response (nextCursor) to fetch the next page',
},
},
request: {
url: (params) => {
const url = new URL('https://public-api.gamma.app/v1.0/themes')
if (params.query) url.searchParams.append('query', params.query)
if (params.limit) url.searchParams.append('limit', String(params.limit))
if (params.after) url.searchParams.append('after', params.after)
return url.toString()
},
method: 'GET',
headers: (params) => ({
'X-API-KEY': params.apiKey,
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
const items = Array.isArray(data.data) ? data.data : Array.isArray(data) ? data : []
return {
success: true,
output: {
themes: items.map(
(theme: {
id?: string
name?: string
type?: string
colorKeywords?: string[]
toneKeywords?: string[]
}) => ({
id: theme.id ?? '',
name: theme.name ?? '',
type: theme.type ?? '',
colorKeywords: theme.colorKeywords ?? [],
toneKeywords: theme.toneKeywords ?? [],
})
),
hasMore: data.hasMore ?? false,
nextCursor: data.nextCursor ?? null,
},
}
},
outputs: {
themes: {
type: 'array',
description: 'List of available themes',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Theme ID (use with themeId parameter)' },
name: { type: 'string', description: 'Theme display name' },
type: { type: 'string', description: 'Theme type: standard or custom' },
colorKeywords: {
type: 'array',
description: 'Color descriptors for this theme',
items: { type: 'string', description: 'Color keyword' },
},
toneKeywords: {
type: 'array',
description: 'Tone descriptors for this theme',
items: { type: 'string', description: 'Tone keyword' },
},
},
},
},
hasMore: {
type: 'boolean',
description: 'Whether more results are available on the next page',
},
nextCursor: {
type: 'string',
description: 'Pagination cursor to pass as the after parameter for the next page',
optional: true,
},
},
}
+163
View File
@@ -0,0 +1,163 @@
import type { ToolResponse } from '@/tools/types'
/**
* Base parameters shared across all Gamma API tools.
*/
interface GammaBaseParams {
apiKey: string
}
/**
* Parameters for the Generate a Gamma tool.
*/
export interface GammaGenerateParams extends GammaBaseParams {
inputText: string
textMode: 'generate' | 'condense' | 'preserve'
format?: 'presentation' | 'document' | 'webpage' | 'social'
themeId?: string
numCards?: number
cardSplit?: 'auto' | 'inputTextBreaks'
cardDimensions?: string
additionalInstructions?: string
exportAs?: 'pdf' | 'pptx'
folderIds?: string
textAmount?: 'brief' | 'medium' | 'detailed' | 'extensive'
textTone?: string
textAudience?: string
textLanguage?: string
imageSource?:
| 'aiGenerated'
| 'pictographic'
| 'unsplash'
| 'webAllImages'
| 'webFreeToUse'
| 'webFreeToUseCommercially'
| 'giphy'
| 'placeholder'
| 'noImages'
imageModel?: string
imageStyle?: string
}
/**
* Parameters for the Generate from Template tool.
*/
export interface GammaGenerateFromTemplateParams extends GammaBaseParams {
gammaId: string
prompt: string
themeId?: string
exportAs?: 'pdf' | 'pptx'
folderIds?: string
imageModel?: string
imageStyle?: string
}
/**
* Parameters for the Check Generation Status tool.
*/
export interface GammaCheckStatusParams extends GammaBaseParams {
generationId: string
}
/**
* Parameters for the List Themes tool.
*/
export interface GammaListThemesParams extends GammaBaseParams {
query?: string
limit?: number
after?: string
}
/**
* Parameters for the List Folders tool.
*/
export interface GammaListFoldersParams extends GammaBaseParams {
query?: string
limit?: number
after?: string
}
/**
* Response for the Generate tool.
*/
export interface GammaGenerateResponse extends ToolResponse {
output: {
generationId: string
}
}
/**
* Response for the Generate from Template tool.
*/
export interface GammaGenerateFromTemplateResponse extends ToolResponse {
output: {
generationId: string
}
}
/**
* Response for the Check Status tool.
*/
export interface GammaCheckStatusResponse extends ToolResponse {
output: {
generationId: string
status: 'pending' | 'completed' | 'failed'
gammaUrl: string | null
credits?: {
deducted: number | null
remaining: number | null
}
error?: {
message: string | null
statusCode: number | null
}
}
}
/**
* Theme object from the Gamma API.
*/
interface GammaTheme {
id: string
name: string
type: string
colorKeywords: string[]
toneKeywords: string[]
}
/**
* Response for the List Themes tool.
*/
export interface GammaListThemesResponse extends ToolResponse {
output: {
themes: GammaTheme[]
hasMore: boolean
nextCursor: string | null
}
}
/**
* Folder object from the Gamma API.
*/
interface GammaFolder {
id: string
name: string
}
/**
* Response for the List Folders tool.
*/
export interface GammaListFoldersResponse extends ToolResponse {
output: {
folders: GammaFolder[]
hasMore: boolean
nextCursor: string | null
}
}
export type GammaResponse =
| GammaGenerateResponse
| GammaGenerateFromTemplateResponse
| GammaCheckStatusResponse
| GammaListThemesResponse
| GammaListFoldersResponse