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 { validateOriginAdapter } from '@agentic/platform-schemas'
|
||||
import { assert, parseZodSchema, sha256 } from '@agentic/platform-core'
|
||||
import { validateAgenticProjectConfig } from '@agentic/platform-schemas'
|
||||
import { validators } from '@agentic/platform-validators'
|
||||
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
|
||||
|
||||
|
@ -99,10 +99,15 @@ export function registerV1DeploymentsCreateDeployment(
|
|||
})
|
||||
}
|
||||
|
||||
// Validate origin config, including any OpenAPI or MCP specs
|
||||
await validateOriginAdapter({
|
||||
...pick(body, 'originUrl', 'originAdapter'),
|
||||
// Validate project config, including:
|
||||
// - pricing plans
|
||||
// - origin adapter config
|
||||
// - origin API base UrL
|
||||
// - origin adapter OpenAPI or MCP specs
|
||||
// - tool definitions
|
||||
const agenticProjectConfig = await validateAgenticProjectConfig(body, {
|
||||
label: `deployment "${deploymentIdentifier}"`,
|
||||
strip: true,
|
||||
logger
|
||||
})
|
||||
|
||||
|
@ -111,6 +116,7 @@ export function registerV1DeploymentsCreateDeployment(
|
|||
.insert(schema.deployments)
|
||||
.values({
|
||||
...body,
|
||||
...agenticProjectConfig,
|
||||
identifier: deploymentIdentifier,
|
||||
hash,
|
||||
userId: user.id,
|
||||
|
@ -139,8 +145,6 @@ export function registerV1DeploymentsCreateDeployment(
|
|||
version: deployment.version!
|
||||
})
|
||||
}
|
||||
// TODO: validate deployment originUrl, originAdapter, originSchema, and
|
||||
// originSchemaVersion
|
||||
|
||||
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
|
||||
|
||||
/**
|
||||
* A `Consumer` is a user who has subscribed to a `Project`.
|
||||
*
|
||||
* Consumers are used to track usage and billing for a project.
|
||||
* 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 for
|
||||
* the platform account, or a customer on the project's connected Stripe
|
||||
* account if the project has Stripe Connect enabled.
|
||||
* 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.
|
||||
*/
|
||||
export const consumers = pgTable(
|
||||
'consumers',
|
||||
|
@ -168,6 +167,15 @@ export const consumerSelectSchema = createSelectSchema(consumers, {
|
|||
// .openapi('Deployment', { type: 'object' })
|
||||
// })
|
||||
.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')
|
||||
|
||||
export const consumerInsertSchema = createInsertSchema(consumers, {
|
||||
|
|
|
@ -41,6 +41,15 @@ import { projects } from './project'
|
|||
import { teams } from './team'
|
||||
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(
|
||||
'deployments',
|
||||
{
|
||||
|
@ -162,6 +171,11 @@ export const deploymentSelectSchema = createSelectSchema(deployments, {
|
|||
// project: z.object({}).optional().openapi('Project', { type: 'object' })
|
||||
// })
|
||||
.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')
|
||||
|
||||
export const deploymentInsertSchema = createInsertSchema(deployments, {
|
||||
|
|
|
@ -43,6 +43,18 @@ import { deployments } from './deployment'
|
|||
import { teams } from './team'
|
||||
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(
|
||||
'projects',
|
||||
{
|
||||
|
@ -210,6 +222,13 @@ export const projectSelectSchema = createSelectSchema(projects, {
|
|||
// .openapi('Deployment', { type: 'object' })
|
||||
// })
|
||||
.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')
|
||||
|
||||
export const projectInsertSchema = createInsertSchema(projects, {
|
||||
|
|
|
@ -29,97 +29,99 @@ export const defaultFreePricingPlan = {
|
|||
]
|
||||
} as const satisfies Readonly<PricingPlan>
|
||||
|
||||
export const agenticProjectConfigSchema = z.object({
|
||||
/**
|
||||
* Required name of the project.
|
||||
*
|
||||
* Must be lower kebab-case with no spaces and between 2 and 64 characters.
|
||||
*
|
||||
* @example "my-project"
|
||||
* @example "linkedin-resolver-23"
|
||||
*/
|
||||
name: z.string().nonempty().describe('Name of the project.'),
|
||||
export const agenticProjectConfigSchema = z
|
||||
.object({
|
||||
/**
|
||||
* Required name of the project.
|
||||
*
|
||||
* Must be lower kebab-case with no spaces and between 2 and 64 characters.
|
||||
*
|
||||
* @example "my-project"
|
||||
* @example "linkedin-resolver-23"
|
||||
*/
|
||||
name: z.string().nonempty().describe('Name of the project.'),
|
||||
|
||||
/** Optional short description of the project. */
|
||||
description: z
|
||||
.string()
|
||||
.describe('A short description of the project.')
|
||||
.optional(),
|
||||
/** Optional short description of the project. */
|
||||
description: z
|
||||
.string()
|
||||
.describe('A short description of the project.')
|
||||
.optional(),
|
||||
|
||||
/** Optional readme documenting the project (supports GitHub-flavored markdown). */
|
||||
readme: z
|
||||
.string()
|
||||
.describe(
|
||||
'A readme documenting the project (supports GitHub-flavored markdown).'
|
||||
)
|
||||
.optional(),
|
||||
/** Optional readme documenting the project (supports GitHub-flavored markdown). */
|
||||
readme: z
|
||||
.string()
|
||||
.describe(
|
||||
'A readme documenting the project (supports GitHub-flavored markdown).'
|
||||
)
|
||||
.optional(),
|
||||
|
||||
/**
|
||||
* Optional logo image URL to use for the project. Logos should have a square aspect ratio.
|
||||
*/
|
||||
iconUrl: z
|
||||
.string()
|
||||
.url()
|
||||
.optional()
|
||||
.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.
|
||||
*/
|
||||
iconUrl: z
|
||||
.string()
|
||||
.url()
|
||||
.optional()
|
||||
.describe(
|
||||
'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. */
|
||||
sourceUrl: z
|
||||
.string()
|
||||
.url()
|
||||
.optional()
|
||||
.describe(
|
||||
'Optional URL to the source code of the project (eg, GitHub repo).'
|
||||
),
|
||||
/** Optional URL to the source code of the project. */
|
||||
sourceUrl: z
|
||||
.string()
|
||||
.url()
|
||||
.optional()
|
||||
.describe(
|
||||
'Optional URL to the source code of the project (eg, GitHub repo).'
|
||||
),
|
||||
|
||||
/** Required origin API HTTPS base URL */
|
||||
originUrl: z.string().url()
|
||||
.describe(`Required base URL of the externally hosted origin API server. Must be a valid \`https\` URL.
|
||||
/** Required origin API HTTPS base URL */
|
||||
originUrl: z.string().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.`),
|
||||
|
||||
/** Optional origin API config */
|
||||
originAdapter: deploymentOriginAdapterSchema.optional().default({
|
||||
location: 'external',
|
||||
type: 'raw'
|
||||
}),
|
||||
/** Optional origin API config */
|
||||
originAdapter: deploymentOriginAdapterSchema.optional().default({
|
||||
location: 'external',
|
||||
type: 'raw'
|
||||
}),
|
||||
|
||||
/** Optional subscription pricing config */
|
||||
pricingPlans: pricingPlanListSchema
|
||||
.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.'
|
||||
)
|
||||
.optional()
|
||||
.default([defaultFreePricingPlan]),
|
||||
/** Optional subscription pricing config */
|
||||
pricingPlans: pricingPlanListSchema
|
||||
.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.'
|
||||
)
|
||||
.optional()
|
||||
.default([defaultFreePricingPlan]),
|
||||
|
||||
/**
|
||||
* Optional list of billing intervals to enable in the pricingPlans.
|
||||
*
|
||||
* Defaults to a single monthly interval `['month']`.
|
||||
*
|
||||
* To add support for annual pricing plans, for example, you can use:
|
||||
* `['month', 'year']`.
|
||||
*
|
||||
* Note that for every pricing interval, you must define a corresponding set
|
||||
* of PricingPlans in the `pricingPlans` array. If you only have one pricing
|
||||
* interval (like the default `month` interval), `pricingPlans` don't need to
|
||||
* specify their `interval` property. Otherwise, all PricingPlans must
|
||||
* specify their `interval` property to differentiate between different
|
||||
* pricing intervals.
|
||||
*/
|
||||
pricingIntervals: pricingIntervalListSchema
|
||||
.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']`.
|
||||
*
|
||||
* To add support for annual pricing plans, for example, you can use:
|
||||
* `['month', 'year']`.
|
||||
*
|
||||
* Note that for every pricing interval, you must define a corresponding set
|
||||
* of PricingPlans in the `pricingPlans` array. If you only have one pricing
|
||||
* interval (like the default `month` interval), `pricingPlans` don't need to
|
||||
* specify their `interval` property. Otherwise, all PricingPlans must
|
||||
* specify their `interval` property to differentiate between different
|
||||
* pricing intervals.
|
||||
*/
|
||||
pricingIntervals: pricingIntervalListSchema
|
||||
.describe(
|
||||
`Optional list of billing intervals to enable in the pricingPlans.
|
||||
|
||||
Defaults to a single monthly interval \`['month']\`.
|
||||
|
||||
To add support for annual pricing plans, for example, you can use: \`['month', 'year']\`.`
|
||||
)
|
||||
.optional()
|
||||
.default(['month'])
|
||||
})
|
||||
)
|
||||
.optional()
|
||||
.default(['month'])
|
||||
})
|
||||
.strip()
|
||||
|
||||
export type AgenticProjectConfigInput = z.input<
|
||||
typeof agenticProjectConfigSchema
|
||||
|
|
|
@ -13,13 +13,21 @@ import { validateOriginAdapter } from './validate-origin-adapter'
|
|||
|
||||
export async function validateAgenticProjectConfig(
|
||||
inputConfig: unknown,
|
||||
opts: { logger?: Logger; cwd?: URL } = {}
|
||||
{
|
||||
strip = false,
|
||||
...opts
|
||||
}: { logger?: Logger; cwd?: URL; strip?: boolean; label?: string } = {}
|
||||
): Promise<AgenticProjectConfig> {
|
||||
const config = parseZodSchema<
|
||||
AgenticProjectConfig,
|
||||
ZodTypeDef,
|
||||
AgenticProjectConfigInput
|
||||
>(agenticProjectConfigSchema, inputConfig)
|
||||
>(
|
||||
strip
|
||||
? agenticProjectConfigSchema.strip()
|
||||
: agenticProjectConfigSchema.strict(),
|
||||
inputConfig
|
||||
)
|
||||
|
||||
const { name, pricingIntervals, pricingPlans, originUrl } = config
|
||||
assert(
|
||||
|
@ -216,8 +224,8 @@ export async function validateAgenticProjectConfig(
|
|||
}
|
||||
|
||||
await validateOriginAdapter({
|
||||
...opts,
|
||||
label: `project "${name}"`,
|
||||
...opts,
|
||||
originUrl,
|
||||
originAdapter: config.originAdapter
|
||||
})
|
||||
|
|
Ładowanie…
Reference in New Issue