kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
pull/715/head
rodzic
9a0fabd498
commit
cdf55f672f
|
@ -1,5 +1,5 @@
|
||||||
import { assert, parseZodSchema, pick, sha256 } from '@agentic/platform-core'
|
import { assert, parseZodSchema, sha256 } from '@agentic/platform-core'
|
||||||
import { validateOriginAdapter } from '@agentic/platform-schemas'
|
import { validateAgenticProjectConfig } from '@agentic/platform-schemas'
|
||||||
import { validators } from '@agentic/platform-validators'
|
import { validators } from '@agentic/platform-validators'
|
||||||
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
|
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
|
||||||
|
|
||||||
|
@ -99,10 +99,15 @@ export function registerV1DeploymentsCreateDeployment(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate origin config, including any OpenAPI or MCP specs
|
// Validate project config, including:
|
||||||
await validateOriginAdapter({
|
// - pricing plans
|
||||||
...pick(body, 'originUrl', 'originAdapter'),
|
// - origin adapter config
|
||||||
|
// - origin API base UrL
|
||||||
|
// - origin adapter OpenAPI or MCP specs
|
||||||
|
// - tool definitions
|
||||||
|
const agenticProjectConfig = await validateAgenticProjectConfig(body, {
|
||||||
label: `deployment "${deploymentIdentifier}"`,
|
label: `deployment "${deploymentIdentifier}"`,
|
||||||
|
strip: true,
|
||||||
logger
|
logger
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -111,6 +116,7 @@ export function registerV1DeploymentsCreateDeployment(
|
||||||
.insert(schema.deployments)
|
.insert(schema.deployments)
|
||||||
.values({
|
.values({
|
||||||
...body,
|
...body,
|
||||||
|
...agenticProjectConfig,
|
||||||
identifier: deploymentIdentifier,
|
identifier: deploymentIdentifier,
|
||||||
hash,
|
hash,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
|
@ -139,8 +145,6 @@ export function registerV1DeploymentsCreateDeployment(
|
||||||
version: deployment.version!
|
version: deployment.version!
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// TODO: validate deployment originUrl, originAdapter, originSchema, and
|
|
||||||
// originSchemaVersion
|
|
||||||
|
|
||||||
return c.json(parseZodSchema(schema.deploymentSelectSchema, deployment))
|
return c.json(parseZodSchema(schema.deploymentSelectSchema, deployment))
|
||||||
})
|
})
|
||||||
|
|
|
@ -38,14 +38,13 @@ import { users } from './user'
|
||||||
// https://docs.rapidapi.com/docs/keys#section-different-api-keys-per-application
|
// https://docs.rapidapi.com/docs/keys#section-different-api-keys-per-application
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `Consumer` is a user who has subscribed to a `Project`.
|
* A `Consumer` represents a user who has subscribed to a `Project` and is used
|
||||||
*
|
* to track usage and billing.
|
||||||
* Consumers are used to track usage and billing for a project.
|
|
||||||
*
|
*
|
||||||
* Consumers are linked to a corresponding Stripe Customer and Subscription.
|
* Consumers are linked to a corresponding Stripe Customer and Subscription.
|
||||||
* The Stripe customer will either be the user's default Stripe Customer for
|
* The Stripe customer will either be the user's default Stripe Customer if the
|
||||||
* the platform account, or a customer on the project's connected Stripe
|
* project uses the default Agentic platform account, or a customer on the project
|
||||||
* account if the project has Stripe Connect enabled.
|
* owner's connected Stripe account if the project has Stripe Connect enabled.
|
||||||
*/
|
*/
|
||||||
export const consumers = pgTable(
|
export const consumers = pgTable(
|
||||||
'consumers',
|
'consumers',
|
||||||
|
@ -168,6 +167,15 @@ export const consumerSelectSchema = createSelectSchema(consumers, {
|
||||||
// .openapi('Deployment', { type: 'object' })
|
// .openapi('Deployment', { type: 'object' })
|
||||||
// })
|
// })
|
||||||
.strip()
|
.strip()
|
||||||
|
.describe(
|
||||||
|
`A Consumer represents a user who has subscribed to a Project and is used
|
||||||
|
to track usage and billing.
|
||||||
|
|
||||||
|
Consumers are linked to a corresponding Stripe Customer and Subscription.
|
||||||
|
The Stripe customer will either be the user's default Stripe Customer if the
|
||||||
|
project uses the default Agentic platform account, or a customer on the project
|
||||||
|
owner's connected Stripe account if the project has Stripe Connect enabled.`
|
||||||
|
)
|
||||||
.openapi('Consumer')
|
.openapi('Consumer')
|
||||||
|
|
||||||
export const consumerInsertSchema = createInsertSchema(consumers, {
|
export const consumerInsertSchema = createInsertSchema(consumers, {
|
||||||
|
|
|
@ -41,6 +41,15 @@ import { projects } from './project'
|
||||||
import { teams } from './team'
|
import { teams } from './team'
|
||||||
import { users } from './user'
|
import { users } from './user'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Deployment is a single, immutable instance of a Project. Each deployment
|
||||||
|
* contains pricing plans, origin server config (OpenAPI or MCP server), tool
|
||||||
|
* definitions, and metadata.
|
||||||
|
*
|
||||||
|
* Deployments are private to a developer or team until they are published, at
|
||||||
|
* which point they are accessible to any customers with access to the parent
|
||||||
|
* Project.
|
||||||
|
*/
|
||||||
export const deployments = pgTable(
|
export const deployments = pgTable(
|
||||||
'deployments',
|
'deployments',
|
||||||
{
|
{
|
||||||
|
@ -162,6 +171,11 @@ export const deploymentSelectSchema = createSelectSchema(deployments, {
|
||||||
// project: z.object({}).optional().openapi('Project', { type: 'object' })
|
// project: z.object({}).optional().openapi('Project', { type: 'object' })
|
||||||
// })
|
// })
|
||||||
.strip()
|
.strip()
|
||||||
|
.describe(
|
||||||
|
`A Deployment is a single, immutable instance of a Project. Each deployment contains pricing plans, origin server config (OpenAPI or MCP server), tool definitions, and metadata.
|
||||||
|
|
||||||
|
Deployments are private to a developer or team until they are published, at which point they are accessible to any customers with access to the parent Project.`
|
||||||
|
)
|
||||||
.openapi('Deployment')
|
.openapi('Deployment')
|
||||||
|
|
||||||
export const deploymentInsertSchema = createInsertSchema(deployments, {
|
export const deploymentInsertSchema = createInsertSchema(deployments, {
|
||||||
|
|
|
@ -43,6 +43,18 @@ import { deployments } from './deployment'
|
||||||
import { teams } from './team'
|
import { teams } from './team'
|
||||||
import { users } from './user'
|
import { users } from './user'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Project represents a single Agentic API product. A Project is comprised of
|
||||||
|
* a series of immutable Deployments, each of which contains pricing data, origin
|
||||||
|
* API config, OpenAPI or MCP specs, tool definitions, and various metadata.
|
||||||
|
*
|
||||||
|
* You can think of Agentic Projects as similar to Vercel projects. They both
|
||||||
|
* hold some common configuration and are comprised of a series of immutable
|
||||||
|
* Deployments.
|
||||||
|
*
|
||||||
|
* Internally, Projects manage all of the Stripe billing resources across
|
||||||
|
* Deployments (Stripe Products, Prices, and Meters for usage-based billing).
|
||||||
|
*/
|
||||||
export const projects = pgTable(
|
export const projects = pgTable(
|
||||||
'projects',
|
'projects',
|
||||||
{
|
{
|
||||||
|
@ -210,6 +222,13 @@ export const projectSelectSchema = createSelectSchema(projects, {
|
||||||
// .openapi('Deployment', { type: 'object' })
|
// .openapi('Deployment', { type: 'object' })
|
||||||
// })
|
// })
|
||||||
.strip()
|
.strip()
|
||||||
|
.describe(
|
||||||
|
`A Project represents a single Agentic API product. A Project is comprised of a series of immutable Deployments, each of which contains pricing data, origin API config, OpenAPI or MCP specs, tool definitions, and various metadata.
|
||||||
|
|
||||||
|
You can think of Agentic Projects as similar to Vercel projects. They both hold some common configuration and are comprised of a series of immutable Deployments.
|
||||||
|
|
||||||
|
Internally, Projects manage all of the Stripe billing resources across Deployments (Stripe Products, Prices, and Meters for usage-based billing).`
|
||||||
|
)
|
||||||
.openapi('Project')
|
.openapi('Project')
|
||||||
|
|
||||||
export const projectInsertSchema = createInsertSchema(projects, {
|
export const projectInsertSchema = createInsertSchema(projects, {
|
||||||
|
|
|
@ -29,97 +29,99 @@ export const defaultFreePricingPlan = {
|
||||||
]
|
]
|
||||||
} as const satisfies Readonly<PricingPlan>
|
} as const satisfies Readonly<PricingPlan>
|
||||||
|
|
||||||
export const agenticProjectConfigSchema = z.object({
|
export const agenticProjectConfigSchema = z
|
||||||
/**
|
.object({
|
||||||
* Required name of the project.
|
/**
|
||||||
*
|
* Required name of the project.
|
||||||
* Must be lower kebab-case with no spaces and between 2 and 64 characters.
|
*
|
||||||
*
|
* Must be lower kebab-case with no spaces and between 2 and 64 characters.
|
||||||
* @example "my-project"
|
*
|
||||||
* @example "linkedin-resolver-23"
|
* @example "my-project"
|
||||||
*/
|
* @example "linkedin-resolver-23"
|
||||||
name: z.string().nonempty().describe('Name of the project.'),
|
*/
|
||||||
|
name: z.string().nonempty().describe('Name of the project.'),
|
||||||
|
|
||||||
/** Optional short description of the project. */
|
/** Optional short description of the project. */
|
||||||
description: z
|
description: z
|
||||||
.string()
|
.string()
|
||||||
.describe('A short description of the project.')
|
.describe('A short description of the project.')
|
||||||
.optional(),
|
.optional(),
|
||||||
|
|
||||||
/** Optional readme documenting the project (supports GitHub-flavored markdown). */
|
/** Optional readme documenting the project (supports GitHub-flavored markdown). */
|
||||||
readme: z
|
readme: z
|
||||||
.string()
|
.string()
|
||||||
.describe(
|
.describe(
|
||||||
'A readme documenting the project (supports GitHub-flavored markdown).'
|
'A readme documenting the project (supports GitHub-flavored markdown).'
|
||||||
)
|
)
|
||||||
.optional(),
|
.optional(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional logo image URL to use for the project. Logos should have a square aspect ratio.
|
* Optional logo image URL to use for the project. Logos should have a square aspect ratio.
|
||||||
*/
|
*/
|
||||||
iconUrl: z
|
iconUrl: z
|
||||||
.string()
|
.string()
|
||||||
.url()
|
.url()
|
||||||
.optional()
|
.optional()
|
||||||
.describe(
|
.describe(
|
||||||
'Optional logo image URL to use for the project. Logos should have a square aspect ratio.'
|
'Optional logo image URL to use for the project. Logos should have a square aspect ratio.'
|
||||||
),
|
),
|
||||||
|
|
||||||
/** Optional URL to the source code of the project. */
|
/** Optional URL to the source code of the project. */
|
||||||
sourceUrl: z
|
sourceUrl: z
|
||||||
.string()
|
.string()
|
||||||
.url()
|
.url()
|
||||||
.optional()
|
.optional()
|
||||||
.describe(
|
.describe(
|
||||||
'Optional URL to the source code of the project (eg, GitHub repo).'
|
'Optional URL to the source code of the project (eg, GitHub repo).'
|
||||||
),
|
),
|
||||||
|
|
||||||
/** Required origin API HTTPS base URL */
|
/** Required origin API HTTPS base URL */
|
||||||
originUrl: z.string().url()
|
originUrl: z.string().url()
|
||||||
.describe(`Required base URL of the externally hosted origin API server. Must be a valid \`https\` URL.
|
.describe(`Required base URL of the externally hosted origin API server. Must be a valid \`https\` URL.
|
||||||
|
|
||||||
NOTE: Agentic currently only supports \`external\` API servers. If you'd like to host your API or MCP server on Agentic's infrastructure, please reach out to support@agentic.so.`),
|
NOTE: Agentic currently only supports \`external\` API servers. If you'd like to host your API or MCP server on Agentic's infrastructure, please reach out to support@agentic.so.`),
|
||||||
|
|
||||||
/** Optional origin API config */
|
/** Optional origin API config */
|
||||||
originAdapter: deploymentOriginAdapterSchema.optional().default({
|
originAdapter: deploymentOriginAdapterSchema.optional().default({
|
||||||
location: 'external',
|
location: 'external',
|
||||||
type: 'raw'
|
type: 'raw'
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/** Optional subscription pricing config */
|
/** Optional subscription pricing config */
|
||||||
pricingPlans: pricingPlanListSchema
|
pricingPlans: pricingPlanListSchema
|
||||||
.describe(
|
.describe(
|
||||||
'List of PricingPlans configuring which Stripe subscriptions should be available for the project. Defaults to a single free plan which is useful for developing and testing.your project.'
|
'List of PricingPlans configuring which Stripe subscriptions should be available for the project. Defaults to a single free plan which is useful for developing and testing.your project.'
|
||||||
)
|
)
|
||||||
.optional()
|
.optional()
|
||||||
.default([defaultFreePricingPlan]),
|
.default([defaultFreePricingPlan]),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional list of billing intervals to enable in the pricingPlans.
|
* Optional list of billing intervals to enable in the pricingPlans.
|
||||||
*
|
*
|
||||||
* Defaults to a single monthly interval `['month']`.
|
* Defaults to a single monthly interval `['month']`.
|
||||||
*
|
*
|
||||||
* To add support for annual pricing plans, for example, you can use:
|
* To add support for annual pricing plans, for example, you can use:
|
||||||
* `['month', 'year']`.
|
* `['month', 'year']`.
|
||||||
*
|
*
|
||||||
* Note that for every pricing interval, you must define a corresponding set
|
* Note that for every pricing interval, you must define a corresponding set
|
||||||
* of PricingPlans in the `pricingPlans` array. If you only have one pricing
|
* of PricingPlans in the `pricingPlans` array. If you only have one pricing
|
||||||
* interval (like the default `month` interval), `pricingPlans` don't need to
|
* interval (like the default `month` interval), `pricingPlans` don't need to
|
||||||
* specify their `interval` property. Otherwise, all PricingPlans must
|
* specify their `interval` property. Otherwise, all PricingPlans must
|
||||||
* specify their `interval` property to differentiate between different
|
* specify their `interval` property to differentiate between different
|
||||||
* pricing intervals.
|
* pricing intervals.
|
||||||
*/
|
*/
|
||||||
pricingIntervals: pricingIntervalListSchema
|
pricingIntervals: pricingIntervalListSchema
|
||||||
.describe(
|
.describe(
|
||||||
`Optional list of billing intervals to enable in the pricingPlans.
|
`Optional list of billing intervals to enable in the pricingPlans.
|
||||||
|
|
||||||
Defaults to a single monthly interval \`['month']\`.
|
Defaults to a single monthly interval \`['month']\`.
|
||||||
|
|
||||||
To add support for annual pricing plans, for example, you can use: \`['month', 'year']\`.`
|
To add support for annual pricing plans, for example, you can use: \`['month', 'year']\`.`
|
||||||
)
|
)
|
||||||
.optional()
|
.optional()
|
||||||
.default(['month'])
|
.default(['month'])
|
||||||
})
|
})
|
||||||
|
.strip()
|
||||||
|
|
||||||
export type AgenticProjectConfigInput = z.input<
|
export type AgenticProjectConfigInput = z.input<
|
||||||
typeof agenticProjectConfigSchema
|
typeof agenticProjectConfigSchema
|
||||||
|
|
|
@ -13,13 +13,21 @@ import { validateOriginAdapter } from './validate-origin-adapter'
|
||||||
|
|
||||||
export async function validateAgenticProjectConfig(
|
export async function validateAgenticProjectConfig(
|
||||||
inputConfig: unknown,
|
inputConfig: unknown,
|
||||||
opts: { logger?: Logger; cwd?: URL } = {}
|
{
|
||||||
|
strip = false,
|
||||||
|
...opts
|
||||||
|
}: { logger?: Logger; cwd?: URL; strip?: boolean; label?: string } = {}
|
||||||
): Promise<AgenticProjectConfig> {
|
): Promise<AgenticProjectConfig> {
|
||||||
const config = parseZodSchema<
|
const config = parseZodSchema<
|
||||||
AgenticProjectConfig,
|
AgenticProjectConfig,
|
||||||
ZodTypeDef,
|
ZodTypeDef,
|
||||||
AgenticProjectConfigInput
|
AgenticProjectConfigInput
|
||||||
>(agenticProjectConfigSchema, inputConfig)
|
>(
|
||||||
|
strip
|
||||||
|
? agenticProjectConfigSchema.strip()
|
||||||
|
: agenticProjectConfigSchema.strict(),
|
||||||
|
inputConfig
|
||||||
|
)
|
||||||
|
|
||||||
const { name, pricingIntervals, pricingPlans, originUrl } = config
|
const { name, pricingIntervals, pricingPlans, originUrl } = config
|
||||||
assert(
|
assert(
|
||||||
|
@ -216,8 +224,8 @@ export async function validateAgenticProjectConfig(
|
||||||
}
|
}
|
||||||
|
|
||||||
await validateOriginAdapter({
|
await validateOriginAdapter({
|
||||||
...opts,
|
|
||||||
label: `project "${name}"`,
|
label: `project "${name}"`,
|
||||||
|
...opts,
|
||||||
originUrl,
|
originUrl,
|
||||||
originAdapter: config.originAdapter
|
originAdapter: config.originAdapter
|
||||||
})
|
})
|
||||||
|
|
Ładowanie…
Reference in New Issue