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": {
"test": "run-s test:*",
"test:lint": "eslint .",
"test:typecheck": "tsc --noEmit"
"test:typecheck": "tsc --noEmit",
"test:unit": "vitest run"
},
"dependencies": {
"@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 { agenticProjectSchema } from '@agentic/platform-schemas'
import {
type AgenticProjectConfigOutput,
agenticProjectConfigSchema
} from '@agentic/platform-schemas'
import { loadConfig } from 'unconfig'
export async function loadAgenticConfig({ cwd }: { cwd?: string }) {
export async function loadAgenticConfig({
cwd
}: {
cwd?: string
}): Promise<AgenticProjectConfigOutput> {
const { config } = await loadConfig({
cwd,
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",
"include": ["src", "*.config.ts"],
"include": ["src", "*.config.ts", "fixtures/**/*.config.ts"],
"exclude": ["node_modules"]
}

Wyświetl plik

@ -23,7 +23,7 @@ interface ParseSchemaOptions {
/**
* 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
*/

Wyświetl plik

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

Wyświetl plik

@ -12,7 +12,7 @@ import { deploymentOriginAdapterSchema, pricingPlanListSchema } from './schemas'
// - optional version
// - optional agentic version
export const agenticProjectSchema = z.object({
export const agenticProjectConfigSchema = z.object({
name: z.string().describe('Name of the project.'),
// 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.`),
// Optional origin API config
originAdapter: deploymentOriginAdapterSchema
.default({
location: 'external',
type: 'raw'
})
.optional(),
originAdapter: deploymentOriginAdapterSchema.default({
location: 'external',
type: 'raw'
}),
// Optional subscription pricing config
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'