feat: improve agentic config parsing / loading

pull/715/head
Travis Fischer 2025-05-25 17:35:22 +07:00
rodzic a7629d57c8
commit 97198ebe66
13 zmienionych plików z 134 dodań i 17 usunięć

Wyświetl plik

@ -0,0 +1,4 @@
{
"name": "My Project",
"originUrl": "https://jsonplaceholder.typicode.com"
}

Wyświetl plik

@ -0,0 +1,6 @@
import { defineConfig } from '@agentic/platform-schemas'
export default defineConfig({
name: 'My Project',
originUrl: 'https://jsonplaceholder.typicode.com'
})

Wyświetl plik

@ -24,7 +24,8 @@
"scripts": { "scripts": {
"test": "run-s test:*", "test": "run-s test:*",
"test:lint": "eslint .", "test:lint": "eslint .",
"test:typecheck": "tsc --noEmit" "test:typecheck": "tsc --noEmit",
"test:unit": "vitest run"
}, },
"dependencies": { "dependencies": {
"@agentic/platform-api-client": "workspace:*", "@agentic/platform-api-client": "workspace:*",

Wyświetl plik

@ -0,0 +1,49 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`loadAgenticConfig > basic-raw-free-json 1`] = `
{
"name": "My Project",
"originAdapter": {
"location": "external",
"type": "raw",
},
"originUrl": "https://jsonplaceholder.typicode.com",
"pricingPlans": [
{
"lineItems": [
{
"amount": 0,
"slug": "base",
"usageType": "licensed",
},
],
"name": "Free",
"slug": "free",
},
],
}
`;
exports[`loadAgenticConfig > basic-raw-free-ts 1`] = `
{
"name": "My Project",
"originAdapter": {
"location": "external",
"type": "raw",
},
"originUrl": "https://jsonplaceholder.typicode.com",
"pricingPlans": [
{
"lineItems": [
{
"amount": 0,
"slug": "base",
"usageType": "licensed",
},
],
"name": "Free",
"slug": "free",
},
],
}
`;

Wyświetl plik

@ -0,0 +1,33 @@
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { describe, expect, test } from 'vitest'
import { loadAgenticConfig } from './load-agentic-config'
const fixtures = ['basic-raw-free-ts', 'basic-raw-free-json']
const fixturesDir = path.join(
fileURLToPath(import.meta.url),
'..',
'..',
'..',
'fixtures'
)
describe('loadAgenticConfig', () => {
for (const fixture of fixtures) {
test(
`${fixture}`,
{
timeout: 60_000
},
async () => {
const fixtureDir = path.join(fixturesDir, fixture)
const config = await loadAgenticConfig({ cwd: fixtureDir })
expect(config).toMatchSnapshot()
}
)
}
})

Wyświetl plik

@ -1,8 +1,15 @@
import { parseZodSchema } from '@agentic/platform-core' import { parseZodSchema } from '@agentic/platform-core'
import { agenticProjectSchema } from '@agentic/platform-schemas' import {
type AgenticProjectConfigOutput,
agenticProjectConfigSchema
} from '@agentic/platform-schemas'
import { loadConfig } from 'unconfig' import { loadConfig } from 'unconfig'
export async function loadAgenticConfig({ cwd }: { cwd?: string }) { export async function loadAgenticConfig({
cwd
}: {
cwd?: string
}): Promise<AgenticProjectConfigOutput> {
const { config } = await loadConfig({ const { config } = await loadConfig({
cwd, cwd,
sources: [ sources: [
@ -13,5 +20,5 @@ export async function loadAgenticConfig({ cwd }: { cwd?: string }) {
] ]
}) })
return parseZodSchema(agenticProjectSchema, config) return parseZodSchema(agenticProjectConfigSchema, config)
} }

Wyświetl plik

@ -1,5 +1,5 @@
{ {
"extends": "@fisch0920/config/tsconfig-node", "extends": "@fisch0920/config/tsconfig-node",
"include": ["src", "*.config.ts"], "include": ["src", "*.config.ts", "fixtures/**/*.config.ts"],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }

Wyświetl plik

@ -23,7 +23,7 @@ interface ParseSchemaOptions {
/** /**
* Validates an OpenAPI spec and bundles it into a single, normalized schema. * Validates an OpenAPI spec and bundles it into a single, normalized schema.
* *
* The input `source` should be a JSON stringified OpenAPI spec (3.0 or 3.1). * The input `source` should point to a valid OpenAPI spec (3.0 or 3.1).
* *
* Adapted from https://github.com/openapi-ts/openapi-typescript/blob/main/packages/openapi-typescript/src/lib/redoc.ts * Adapted from https://github.com/openapi-ts/openapi-typescript/blob/main/packages/openapi-typescript/src/lib/redoc.ts
*/ */

Wyświetl plik

@ -1,12 +1,12 @@
import restoreCursor from 'restore-cursor' import restoreCursor from 'restore-cursor'
import { zodToJsonSchema } from 'zod-to-json-schema' import { zodToJsonSchema } from 'zod-to-json-schema'
import { agenticProjectSchema } from '../src' import { agenticProjectConfigSchema } from '../src'
async function main() { async function main() {
restoreCursor() restoreCursor()
const tempJsonSchema = zodToJsonSchema(agenticProjectSchema) const tempJsonSchema = zodToJsonSchema(agenticProjectConfigSchema)
const publicJsonSchema = { const publicJsonSchema = {
...tempJsonSchema, ...tempJsonSchema,

Wyświetl plik

@ -12,7 +12,7 @@ import { deploymentOriginAdapterSchema, pricingPlanListSchema } from './schemas'
// - optional version // - optional version
// - optional agentic version // - optional agentic version
export const agenticProjectSchema = z.object({ export const agenticProjectConfigSchema = z.object({
name: z.string().describe('Name of the project.'), name: z.string().describe('Name of the project.'),
// Metadata // Metadata
@ -46,12 +46,10 @@ export const agenticProjectSchema = z.object({
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 originAdapter: deploymentOriginAdapterSchema.default({
.default({ location: 'external',
location: 'external', type: 'raw'
type: 'raw' }),
})
.optional(),
// Optional subscription pricing config // Optional subscription pricing config
pricingPlans: pricingPlanListSchema pricingPlans: pricingPlanListSchema
@ -72,4 +70,9 @@ NOTE: Agentic currently only supports \`external\` API servers. If you'd like to
} }
]) ])
}) })
export type AgenticProject = z.infer<typeof agenticProjectSchema> export type AgenticProjectConfigInput = z.input<
typeof agenticProjectConfigSchema
>
export type AgenticProjectConfigOutput = z.output<
typeof agenticProjectConfigSchema
>

Wyświetl plik

@ -0,0 +1,13 @@
import { parseZodSchema } from '@agentic/platform-core'
import {
type AgenticProjectConfigInput,
type AgenticProjectConfigOutput,
agenticProjectConfigSchema
} from './agentic-project-config-schema'
export function defineConfig(
config: AgenticProjectConfigInput
): AgenticProjectConfigOutput {
return parseZodSchema(agenticProjectConfigSchema, config)
}

Wyświetl plik

@ -1,2 +1,3 @@
export * from './agentic-project-schema' export * from './agentic-project-config-schema'
export * from './define-config'
export * from './schemas' export * from './schemas'