@wp-typia/project-tools 0.19.3 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/dist/runtime/ability-spec.d.ts +90 -0
- package/dist/runtime/ability-spec.js +51 -0
- package/dist/runtime/ai-artifacts.d.ts +39 -0
- package/dist/runtime/ai-artifacts.js +68 -0
- package/dist/runtime/ai-feature-artifacts.d.ts +85 -0
- package/dist/runtime/ai-feature-artifacts.js +139 -0
- package/dist/runtime/ai-feature-capability.d.ts +114 -0
- package/dist/runtime/ai-feature-capability.js +150 -0
- package/dist/runtime/block-generator-service-spec.js +6 -0
- package/dist/runtime/cli-add-shared.d.ts +32 -1
- package/dist/runtime/cli-add-shared.js +44 -0
- package/dist/runtime/cli-add-workspace-ability.d.ts +8 -0
- package/dist/runtime/cli-add-workspace-ability.js +810 -0
- package/dist/runtime/cli-add-workspace-ai-anchors.d.ts +22 -0
- package/dist/runtime/cli-add-workspace-ai-anchors.js +277 -0
- package/dist/runtime/cli-add-workspace-ai-source-emitters.d.ts +28 -0
- package/dist/runtime/cli-add-workspace-ai-source-emitters.js +346 -0
- package/dist/runtime/cli-add-workspace-ai.d.ts +14 -0
- package/dist/runtime/cli-add-workspace-ai.js +484 -0
- package/dist/runtime/cli-add-workspace.d.ts +10 -0
- package/dist/runtime/cli-add-workspace.js +10 -0
- package/dist/runtime/cli-add.d.ts +1 -1
- package/dist/runtime/cli-add.js +1 -1
- package/dist/runtime/cli-core.d.ts +3 -1
- package/dist/runtime/cli-core.js +3 -1
- package/dist/runtime/cli-doctor-workspace.js +140 -1
- package/dist/runtime/cli-help.js +4 -0
- package/dist/runtime/index.d.ts +3 -1
- package/dist/runtime/index.js +2 -1
- package/dist/runtime/scaffold-compatibility.d.ts +65 -0
- package/dist/runtime/scaffold-compatibility.js +152 -0
- package/dist/runtime/scaffold-template-variable-groups.d.ts +2 -0
- package/dist/runtime/scaffold-template-variables.js +6 -0
- package/dist/runtime/scaffold.d.ts +3 -0
- package/dist/runtime/typia-llm.d.ts +213 -0
- package/dist/runtime/typia-llm.js +348 -0
- package/dist/runtime/wordpress-ai.d.ts +122 -0
- package/dist/runtime/wordpress-ai.js +177 -0
- package/dist/runtime/workspace-inventory.d.ts +51 -4
- package/dist/runtime/workspace-inventory.js +157 -4
- package/package.json +12 -2
- package/templates/_shared/base/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/_shared/compound/core/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/_shared/compound/persistence-auth/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/_shared/compound/persistence-public/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/_shared/persistence/auth/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/_shared/persistence/core/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/_shared/persistence/public/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/query-loop/{{slugKebabCase}}.php.mustache +3 -3
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import type { ArtifactSyncExecutionOptions, EndpointManifestDefinition, EndpointManifestEndpointDefinition } from '@wp-typia/block-runtime/metadata-core';
|
|
2
|
+
import type { ILlmFunction, ILlmSchema, ILlmStructuredOutput } from 'typia';
|
|
3
|
+
import { type EndpointAuthIntent, type EndpointWordPressAuthDefinition } from './schema-core.js';
|
|
4
|
+
/**
|
|
5
|
+
* Method-level descriptor projected from an endpoint manifest for a generated
|
|
6
|
+
* `typia.llm` controller interface.
|
|
7
|
+
*/
|
|
8
|
+
export interface TypiaLlmEndpointMethodDescriptor {
|
|
9
|
+
/** Normalized auth intent derived from the endpoint manifest. */
|
|
10
|
+
authIntent: EndpointAuthIntent;
|
|
11
|
+
/** Optional auth mode propagated from legacy manifest metadata. */
|
|
12
|
+
authMode?: EndpointManifestEndpointDefinition['authMode'];
|
|
13
|
+
/** Human-readable operation summary. */
|
|
14
|
+
description?: string;
|
|
15
|
+
/** Input type used by the generated controller method, or null for no input. */
|
|
16
|
+
inputTypeName: string | null;
|
|
17
|
+
/** HTTP method from the source endpoint manifest. */
|
|
18
|
+
method: EndpointManifestEndpointDefinition['method'];
|
|
19
|
+
/** Stable operation identifier used as the generated method name. */
|
|
20
|
+
operationId: string;
|
|
21
|
+
/** Output type used by the generated controller method. */
|
|
22
|
+
outputTypeName: string;
|
|
23
|
+
/** REST path from the source endpoint manifest. */
|
|
24
|
+
path: string;
|
|
25
|
+
/** Tags copied from the source endpoint manifest. */
|
|
26
|
+
tags: readonly string[];
|
|
27
|
+
/** Optional WordPress auth overlay preserved for downstream adapters. */
|
|
28
|
+
wordpressAuth?: EndpointWordPressAuthDefinition;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Configures the generated TypeScript module that asks `typia.llm` to derive
|
|
32
|
+
* function-calling and structured-output artifacts from canonical contracts.
|
|
33
|
+
*/
|
|
34
|
+
export interface RenderTypiaLlmModuleOptions {
|
|
35
|
+
/** Export name for the generated `typia.llm.application<...>()` value. */
|
|
36
|
+
applicationExportName: string;
|
|
37
|
+
/** Generated controller interface name. */
|
|
38
|
+
interfaceName: string;
|
|
39
|
+
/** Endpoint manifest that owns REST operation metadata and source type names. */
|
|
40
|
+
manifest: EndpointManifestDefinition;
|
|
41
|
+
/** Export name for the generated `typia.llm.structuredOutput<...>()` value. */
|
|
42
|
+
structuredOutputExportName: string;
|
|
43
|
+
/** TypeScript output type used for structured-output projection. */
|
|
44
|
+
structuredOutputTypeName: string;
|
|
45
|
+
/** Import path from the generated module to the canonical TypeScript contracts. */
|
|
46
|
+
typesImportPath: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Configures writing or checking the generated `typia.llm` adapter module.
|
|
50
|
+
*/
|
|
51
|
+
export interface SyncTypiaLlmAdapterModuleOptions extends ArtifactSyncExecutionOptions, RenderTypiaLlmModuleOptions {
|
|
52
|
+
/** Destination path for the generated TypeScript adapter module. */
|
|
53
|
+
generatedSourceFile: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Describes the generated adapter module and where it was written or checked.
|
|
57
|
+
*/
|
|
58
|
+
export interface SyncTypiaLlmAdapterModuleResult {
|
|
59
|
+
/** True when the source file was only verified, false when it was written. */
|
|
60
|
+
check: boolean;
|
|
61
|
+
/** Generated endpoint method descriptors used by the module renderer. */
|
|
62
|
+
methodDescriptors: TypiaLlmEndpointMethodDescriptor[];
|
|
63
|
+
/** Rendered TypeScript module source. */
|
|
64
|
+
source: string;
|
|
65
|
+
/** Destination path for the generated TypeScript adapter module. */
|
|
66
|
+
sourceFile: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Function schema shape projected from a compiled `typia.llm.application(...)`
|
|
70
|
+
* result.
|
|
71
|
+
*/
|
|
72
|
+
export interface TypiaLlmFunctionLike extends Pick<ILlmFunction, 'description' | 'name' | 'output' | 'parameters'> {
|
|
73
|
+
/** Function description generated by `typia.llm`. */
|
|
74
|
+
description?: string;
|
|
75
|
+
/** Function name generated by `typia.llm`. */
|
|
76
|
+
name: string;
|
|
77
|
+
/** Optional output schema generated by `typia.llm`. */
|
|
78
|
+
output?: ILlmSchema.IParameters;
|
|
79
|
+
/** Function parameter schema generated by `typia.llm`. */
|
|
80
|
+
parameters: ILlmSchema.IParameters;
|
|
81
|
+
/** Optional tags generated by `typia.llm`. */
|
|
82
|
+
tags?: readonly string[];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Application shape projected from a compiled `typia.llm.application(...)`
|
|
86
|
+
* result.
|
|
87
|
+
*/
|
|
88
|
+
export interface TypiaLlmApplicationLike {
|
|
89
|
+
/** Function schemas generated by `typia.llm`. */
|
|
90
|
+
functions: readonly TypiaLlmFunctionLike[];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Structured-output shape projected from a compiled
|
|
94
|
+
* `typia.llm.structuredOutput(...)` result.
|
|
95
|
+
*/
|
|
96
|
+
export interface TypiaLlmStructuredOutputLike extends Pick<ILlmStructuredOutput, 'parameters'> {
|
|
97
|
+
/** Structured output parameters generated by `typia.llm`. */
|
|
98
|
+
parameters: ILlmStructuredOutput['parameters'];
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* JSON-friendly function artifact for downstream adapter consumers.
|
|
102
|
+
*/
|
|
103
|
+
export interface ProjectedTypiaLlmFunctionArtifact {
|
|
104
|
+
/** Function description generated by `typia.llm`. */
|
|
105
|
+
description?: string;
|
|
106
|
+
/** Function name generated by `typia.llm`. */
|
|
107
|
+
name: string;
|
|
108
|
+
/** Optional output schema generated by `typia.llm`. */
|
|
109
|
+
output?: ILlmSchema.IParameters;
|
|
110
|
+
/** Function parameter schema generated by `typia.llm`. */
|
|
111
|
+
parameters: ILlmSchema.IParameters;
|
|
112
|
+
/** Optional tags generated by `typia.llm`. */
|
|
113
|
+
tags?: string[];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* JSON-friendly application artifact for downstream adapter consumers.
|
|
117
|
+
*/
|
|
118
|
+
export interface ProjectedTypiaLlmApplicationArtifact {
|
|
119
|
+
/** Function-calling artifacts generated by `typia.llm`. */
|
|
120
|
+
functions: ProjectedTypiaLlmFunctionArtifact[];
|
|
121
|
+
/** Source metadata that keeps the artifact tied to canonical contracts. */
|
|
122
|
+
generatedFrom: {
|
|
123
|
+
baselineOpenApiPath?: string;
|
|
124
|
+
blockSlug: string;
|
|
125
|
+
manifestSource: 'endpoint-manifest+typescript';
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* JSON-friendly structured-output artifact for downstream adapter consumers.
|
|
130
|
+
*/
|
|
131
|
+
export interface ProjectedTypiaLlmStructuredOutputArtifact {
|
|
132
|
+
/** Source metadata that keeps the artifact tied to canonical contracts. */
|
|
133
|
+
generatedFrom: {
|
|
134
|
+
aiSchemaPath?: string;
|
|
135
|
+
blockSlug: string;
|
|
136
|
+
outputTypeName: string;
|
|
137
|
+
};
|
|
138
|
+
/** Structured output parameters generated by `typia.llm`. */
|
|
139
|
+
parameters: ILlmStructuredOutput['parameters'];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Configures projection of a compiled `typia.llm.application(...)` result into
|
|
143
|
+
* the JSON-friendly adapter artifact.
|
|
144
|
+
*/
|
|
145
|
+
export interface ProjectTypiaLlmApplicationArtifactOptions {
|
|
146
|
+
/** Compiled application value produced by `typia.llm.application(...)`. */
|
|
147
|
+
application: TypiaLlmApplicationLike;
|
|
148
|
+
/** Source metadata for the generated JSON artifact. */
|
|
149
|
+
generatedFrom: ProjectedTypiaLlmApplicationArtifact['generatedFrom'];
|
|
150
|
+
/** Optional hook for adapter-specific function schema normalization. */
|
|
151
|
+
transformFunction?: (functionArtifact: ProjectedTypiaLlmFunctionArtifact, functionSchema: TypiaLlmFunctionLike) => ProjectedTypiaLlmFunctionArtifact;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Configures projection of a compiled `typia.llm.structuredOutput(...)` result
|
|
155
|
+
* into the JSON-friendly adapter artifact.
|
|
156
|
+
*/
|
|
157
|
+
export interface ProjectTypiaLlmStructuredOutputArtifactOptions {
|
|
158
|
+
/** Source metadata for the generated JSON artifact. */
|
|
159
|
+
generatedFrom: ProjectedTypiaLlmStructuredOutputArtifact['generatedFrom'];
|
|
160
|
+
/** Compiled structured-output value produced by `typia.llm.structuredOutput(...)`. */
|
|
161
|
+
structuredOutput: TypiaLlmStructuredOutputLike;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Builds the generated controller method descriptors that bridge endpoint
|
|
165
|
+
* manifests to `typia.llm` TypeScript interfaces.
|
|
166
|
+
*
|
|
167
|
+
* @param manifest Endpoint manifest that owns operation and source type names.
|
|
168
|
+
* @returns Ordered method descriptors matching the manifest endpoints.
|
|
169
|
+
* @throws When an endpoint has ambiguous query/body input mapping.
|
|
170
|
+
* @throws When an endpoint references a missing input or output contract.
|
|
171
|
+
*/
|
|
172
|
+
export declare function buildTypiaLlmEndpointMethodDescriptors(manifest: EndpointManifestDefinition): TypiaLlmEndpointMethodDescriptor[];
|
|
173
|
+
/**
|
|
174
|
+
* Renders a build-time-only TypeScript module that invokes `typia.llm` against
|
|
175
|
+
* canonical manifest-owned contracts.
|
|
176
|
+
*
|
|
177
|
+
* @param options Render options for the generated adapter module.
|
|
178
|
+
* @returns The generated TypeScript source.
|
|
179
|
+
*/
|
|
180
|
+
export declare function renderTypiaLlmModule({ applicationExportName, interfaceName, manifest, structuredOutputExportName, structuredOutputTypeName, typesImportPath, }: RenderTypiaLlmModuleOptions): string;
|
|
181
|
+
/**
|
|
182
|
+
* Writes or verifies the generated build-time `typia.llm` adapter module. The
|
|
183
|
+
* returned TypeScript source still needs to be compiled by the consuming
|
|
184
|
+
* project's Typia transformer before JSON artifacts can be read from it.
|
|
185
|
+
*
|
|
186
|
+
* @param options Generated module destination plus render options.
|
|
187
|
+
* @returns Rendered source, method descriptors, and the checked/written file path.
|
|
188
|
+
*/
|
|
189
|
+
export declare function syncTypiaLlmAdapterModule({ check, generatedSourceFile, ...renderOptions }: SyncTypiaLlmAdapterModuleOptions): Promise<SyncTypiaLlmAdapterModuleResult>;
|
|
190
|
+
/**
|
|
191
|
+
* Projects one compiled `typia.llm` function schema into a JSON-friendly
|
|
192
|
+
* artifact record.
|
|
193
|
+
*
|
|
194
|
+
* @param functionSchema Function schema from a compiled `typia.llm.application(...)`.
|
|
195
|
+
* @returns JSON-friendly function artifact.
|
|
196
|
+
*/
|
|
197
|
+
export declare function projectTypiaLlmApplicationFunction(functionSchema: TypiaLlmFunctionLike): ProjectedTypiaLlmFunctionArtifact;
|
|
198
|
+
/**
|
|
199
|
+
* Projects a compiled `typia.llm.application(...)` result into a JSON-friendly
|
|
200
|
+
* downstream adapter artifact.
|
|
201
|
+
*
|
|
202
|
+
* @param options Compiled application value and source metadata.
|
|
203
|
+
* @returns JSON-friendly application artifact.
|
|
204
|
+
*/
|
|
205
|
+
export declare function projectTypiaLlmApplicationArtifact({ application, generatedFrom, transformFunction, }: ProjectTypiaLlmApplicationArtifactOptions): ProjectedTypiaLlmApplicationArtifact;
|
|
206
|
+
/**
|
|
207
|
+
* Projects a compiled `typia.llm.structuredOutput(...)` result into a
|
|
208
|
+
* JSON-friendly downstream adapter artifact.
|
|
209
|
+
*
|
|
210
|
+
* @param options Compiled structured-output value and source metadata.
|
|
211
|
+
* @returns JSON-friendly structured-output artifact.
|
|
212
|
+
*/
|
|
213
|
+
export declare function projectTypiaLlmStructuredOutputArtifact({ generatedFrom, structuredOutput, }: ProjectTypiaLlmStructuredOutputArtifactOptions): ProjectedTypiaLlmStructuredOutputArtifact;
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { cloneJsonValue } from './json-utils.js';
|
|
4
|
+
import { normalizeEndpointAuthDefinition, } from './schema-core.js';
|
|
5
|
+
const TYPESCRIPT_RESERVED_WORDS = new Set([
|
|
6
|
+
'abstract',
|
|
7
|
+
'any',
|
|
8
|
+
'as',
|
|
9
|
+
'asserts',
|
|
10
|
+
'async',
|
|
11
|
+
'await',
|
|
12
|
+
'bigint',
|
|
13
|
+
'boolean',
|
|
14
|
+
'break',
|
|
15
|
+
'case',
|
|
16
|
+
'catch',
|
|
17
|
+
'class',
|
|
18
|
+
'const',
|
|
19
|
+
'constructor',
|
|
20
|
+
'continue',
|
|
21
|
+
'debugger',
|
|
22
|
+
'declare',
|
|
23
|
+
'default',
|
|
24
|
+
'delete',
|
|
25
|
+
'do',
|
|
26
|
+
'else',
|
|
27
|
+
'enum',
|
|
28
|
+
'export',
|
|
29
|
+
'extends',
|
|
30
|
+
'false',
|
|
31
|
+
'finally',
|
|
32
|
+
'for',
|
|
33
|
+
'from',
|
|
34
|
+
'function',
|
|
35
|
+
'get',
|
|
36
|
+
'global',
|
|
37
|
+
'if',
|
|
38
|
+
'implements',
|
|
39
|
+
'import',
|
|
40
|
+
'in',
|
|
41
|
+
'infer',
|
|
42
|
+
'instanceof',
|
|
43
|
+
'interface',
|
|
44
|
+
'is',
|
|
45
|
+
'keyof',
|
|
46
|
+
'let',
|
|
47
|
+
'module',
|
|
48
|
+
'namespace',
|
|
49
|
+
'never',
|
|
50
|
+
'new',
|
|
51
|
+
'null',
|
|
52
|
+
'number',
|
|
53
|
+
'object',
|
|
54
|
+
'of',
|
|
55
|
+
'package',
|
|
56
|
+
'private',
|
|
57
|
+
'protected',
|
|
58
|
+
'public',
|
|
59
|
+
'readonly',
|
|
60
|
+
'require',
|
|
61
|
+
'return',
|
|
62
|
+
'satisfies',
|
|
63
|
+
'set',
|
|
64
|
+
'static',
|
|
65
|
+
'string',
|
|
66
|
+
'super',
|
|
67
|
+
'switch',
|
|
68
|
+
'symbol',
|
|
69
|
+
'this',
|
|
70
|
+
'throw',
|
|
71
|
+
'true',
|
|
72
|
+
'try',
|
|
73
|
+
'type',
|
|
74
|
+
'typeof',
|
|
75
|
+
'undefined',
|
|
76
|
+
'unique',
|
|
77
|
+
'unknown',
|
|
78
|
+
'var',
|
|
79
|
+
'void',
|
|
80
|
+
'while',
|
|
81
|
+
'with',
|
|
82
|
+
'yield',
|
|
83
|
+
]);
|
|
84
|
+
function cloneJsonValueIfDefined(value) {
|
|
85
|
+
return value === undefined ? undefined : cloneJsonValue(value);
|
|
86
|
+
}
|
|
87
|
+
function getEndpointInputTypeName(manifest, endpoint) {
|
|
88
|
+
if (endpoint.bodyContract && endpoint.queryContract) {
|
|
89
|
+
throw new Error(`Endpoint "${endpoint.operationId}" defines both bodyContract and queryContract; typia.llm input mapping is ambiguous.`);
|
|
90
|
+
}
|
|
91
|
+
const contractName = endpoint.method === 'GET'
|
|
92
|
+
? endpoint.queryContract ?? null
|
|
93
|
+
: endpoint.bodyContract ?? endpoint.queryContract ?? null;
|
|
94
|
+
if (!contractName) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const contract = manifest.contracts[contractName];
|
|
98
|
+
if (!contract) {
|
|
99
|
+
throw new Error(`Endpoint "${endpoint.operationId}" references missing input contract "${contractName}".`);
|
|
100
|
+
}
|
|
101
|
+
return contract.sourceTypeName;
|
|
102
|
+
}
|
|
103
|
+
function getEndpointOutputTypeName(manifest, endpoint) {
|
|
104
|
+
const contract = manifest.contracts[endpoint.responseContract];
|
|
105
|
+
if (!contract) {
|
|
106
|
+
throw new Error(`Endpoint "${endpoint.operationId}" references missing response contract "${endpoint.responseContract}".`);
|
|
107
|
+
}
|
|
108
|
+
return contract.sourceTypeName;
|
|
109
|
+
}
|
|
110
|
+
function escapeJsDocLine(line) {
|
|
111
|
+
return line.replace(/\*\//g, '* /');
|
|
112
|
+
}
|
|
113
|
+
function normalizeGeneratedArtifactContent(content) {
|
|
114
|
+
return content.replace(/\r\n?/g, '\n');
|
|
115
|
+
}
|
|
116
|
+
function renderDescriptionJsDocLines(method) {
|
|
117
|
+
const description = method.description && method.description.trim().length > 0
|
|
118
|
+
? method.description
|
|
119
|
+
: method.operationId;
|
|
120
|
+
const descriptionLines = description
|
|
121
|
+
.replace(/\r\n?/g, '\n')
|
|
122
|
+
.split('\n')
|
|
123
|
+
.map((line) => line.trim().replace(/\s+/g, ' '))
|
|
124
|
+
.filter(Boolean);
|
|
125
|
+
return (descriptionLines.length > 0
|
|
126
|
+
? descriptionLines
|
|
127
|
+
: [method.operationId]).map((line) => ` * ${escapeJsDocLine(line)}`);
|
|
128
|
+
}
|
|
129
|
+
function renderMethodJsDoc(method) {
|
|
130
|
+
const lines = [
|
|
131
|
+
'/**',
|
|
132
|
+
...renderDescriptionJsDocLines(method),
|
|
133
|
+
' *',
|
|
134
|
+
` * REST path: ${method.method} ${method.path}`,
|
|
135
|
+
` * Auth intent: ${method.authIntent}`,
|
|
136
|
+
...(method.wordpressAuth
|
|
137
|
+
? [
|
|
138
|
+
` * WordPress auth: ${method.wordpressAuth.mechanism}${method.wordpressAuth.publicTokenField
|
|
139
|
+
? ` (field: ${method.wordpressAuth.publicTokenField})`
|
|
140
|
+
: ''}`,
|
|
141
|
+
]
|
|
142
|
+
: []),
|
|
143
|
+
...method.tags.map((tag) => ` * @tag ${escapeJsDocLine(tag)}`),
|
|
144
|
+
' */',
|
|
145
|
+
];
|
|
146
|
+
return lines.join('\n');
|
|
147
|
+
}
|
|
148
|
+
function renderMethodSignature(method) {
|
|
149
|
+
const inputSignature = method.inputTypeName === null ? '' : `input: ${method.inputTypeName}`;
|
|
150
|
+
const methodName = /^[$A-Z_][$0-9A-Z_]*$/i.test(method.operationId) &&
|
|
151
|
+
!TYPESCRIPT_RESERVED_WORDS.has(method.operationId)
|
|
152
|
+
? method.operationId
|
|
153
|
+
: JSON.stringify(method.operationId);
|
|
154
|
+
return `${methodName}(${inputSignature}): ${method.outputTypeName};`;
|
|
155
|
+
}
|
|
156
|
+
function renderTypiaLlmModuleFromMethodDescriptors({ applicationExportName, interfaceName, structuredOutputExportName, structuredOutputTypeName, typesImportPath, }, methods) {
|
|
157
|
+
const importedTypeNames = new Set([structuredOutputTypeName]);
|
|
158
|
+
for (const method of methods) {
|
|
159
|
+
importedTypeNames.add(method.outputTypeName);
|
|
160
|
+
if (method.inputTypeName) {
|
|
161
|
+
importedTypeNames.add(method.inputTypeName);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const imports = Array.from(importedTypeNames).sort().join(',\n\t');
|
|
165
|
+
const methodBlocks = methods
|
|
166
|
+
.map((method) => {
|
|
167
|
+
const jsDoc = renderMethodJsDoc(method)
|
|
168
|
+
.split('\n')
|
|
169
|
+
.map((line) => `\t${line}`)
|
|
170
|
+
.join('\n');
|
|
171
|
+
return `${jsDoc}\n\t${renderMethodSignature(method)}`;
|
|
172
|
+
})
|
|
173
|
+
.join('\n\n');
|
|
174
|
+
return `import typia from "typia";
|
|
175
|
+
import type {
|
|
176
|
+
\t${imports},
|
|
177
|
+
} from "${typesImportPath}";
|
|
178
|
+
|
|
179
|
+
export interface ${interfaceName} {
|
|
180
|
+
${methodBlocks}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export const ${applicationExportName} =
|
|
184
|
+
\ttypia.llm.application<${interfaceName}>();
|
|
185
|
+
|
|
186
|
+
export const ${structuredOutputExportName} =
|
|
187
|
+
\ttypia.llm.structuredOutput<${structuredOutputTypeName}>();
|
|
188
|
+
`;
|
|
189
|
+
}
|
|
190
|
+
async function reconcileGeneratedTypiaLlmArtifacts(artifacts, check) {
|
|
191
|
+
if (!check) {
|
|
192
|
+
for (const artifact of artifacts) {
|
|
193
|
+
await mkdir(path.dirname(artifact.filePath), {
|
|
194
|
+
recursive: true,
|
|
195
|
+
});
|
|
196
|
+
await writeFile(artifact.filePath, artifact.content, 'utf8');
|
|
197
|
+
}
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const issues = [];
|
|
201
|
+
for (const artifact of artifacts) {
|
|
202
|
+
try {
|
|
203
|
+
const current = normalizeGeneratedArtifactContent(await readFile(artifact.filePath, 'utf8'));
|
|
204
|
+
const expected = normalizeGeneratedArtifactContent(artifact.content);
|
|
205
|
+
if (current !== expected) {
|
|
206
|
+
issues.push(`- ${artifact.filePath} (stale)`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
const code = error && typeof error === 'object' && 'code' in error
|
|
211
|
+
? error.code
|
|
212
|
+
: undefined;
|
|
213
|
+
if (code === 'ENOENT') {
|
|
214
|
+
issues.push(`- ${artifact.filePath} (missing)`);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
issues.push(`- ${artifact.filePath} (unreadable: ${error instanceof Error ? error.message : code ?? 'unknown'})`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (issues.length > 0) {
|
|
221
|
+
throw new Error(`Generated typia.llm artifacts are missing or stale:\n${issues.join('\n')}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Builds the generated controller method descriptors that bridge endpoint
|
|
226
|
+
* manifests to `typia.llm` TypeScript interfaces.
|
|
227
|
+
*
|
|
228
|
+
* @param manifest Endpoint manifest that owns operation and source type names.
|
|
229
|
+
* @returns Ordered method descriptors matching the manifest endpoints.
|
|
230
|
+
* @throws When an endpoint has ambiguous query/body input mapping.
|
|
231
|
+
* @throws When an endpoint references a missing input or output contract.
|
|
232
|
+
*/
|
|
233
|
+
export function buildTypiaLlmEndpointMethodDescriptors(manifest) {
|
|
234
|
+
return manifest.endpoints.map((endpoint) => {
|
|
235
|
+
const normalizedAuth = normalizeEndpointAuthDefinition(endpoint);
|
|
236
|
+
return {
|
|
237
|
+
authIntent: normalizedAuth.auth,
|
|
238
|
+
...(normalizedAuth.authMode ? { authMode: normalizedAuth.authMode } : {}),
|
|
239
|
+
description: endpoint.summary,
|
|
240
|
+
inputTypeName: getEndpointInputTypeName(manifest, endpoint),
|
|
241
|
+
method: endpoint.method,
|
|
242
|
+
operationId: endpoint.operationId,
|
|
243
|
+
outputTypeName: getEndpointOutputTypeName(manifest, endpoint),
|
|
244
|
+
path: endpoint.path,
|
|
245
|
+
tags: endpoint.tags ?? [],
|
|
246
|
+
...(normalizedAuth.wordpressAuth
|
|
247
|
+
? { wordpressAuth: normalizedAuth.wordpressAuth }
|
|
248
|
+
: {}),
|
|
249
|
+
};
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Renders a build-time-only TypeScript module that invokes `typia.llm` against
|
|
254
|
+
* canonical manifest-owned contracts.
|
|
255
|
+
*
|
|
256
|
+
* @param options Render options for the generated adapter module.
|
|
257
|
+
* @returns The generated TypeScript source.
|
|
258
|
+
*/
|
|
259
|
+
export function renderTypiaLlmModule({ applicationExportName, interfaceName, manifest, structuredOutputExportName, structuredOutputTypeName, typesImportPath, }) {
|
|
260
|
+
return renderTypiaLlmModuleFromMethodDescriptors({
|
|
261
|
+
applicationExportName,
|
|
262
|
+
interfaceName,
|
|
263
|
+
structuredOutputExportName,
|
|
264
|
+
structuredOutputTypeName,
|
|
265
|
+
typesImportPath,
|
|
266
|
+
}, buildTypiaLlmEndpointMethodDescriptors(manifest));
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Writes or verifies the generated build-time `typia.llm` adapter module. The
|
|
270
|
+
* returned TypeScript source still needs to be compiled by the consuming
|
|
271
|
+
* project's Typia transformer before JSON artifacts can be read from it.
|
|
272
|
+
*
|
|
273
|
+
* @param options Generated module destination plus render options.
|
|
274
|
+
* @returns Rendered source, method descriptors, and the checked/written file path.
|
|
275
|
+
*/
|
|
276
|
+
export async function syncTypiaLlmAdapterModule({ check = false, generatedSourceFile, ...renderOptions }) {
|
|
277
|
+
const methodDescriptors = buildTypiaLlmEndpointMethodDescriptors(renderOptions.manifest);
|
|
278
|
+
const source = renderTypiaLlmModuleFromMethodDescriptors(renderOptions, methodDescriptors);
|
|
279
|
+
await reconcileGeneratedTypiaLlmArtifacts([
|
|
280
|
+
{
|
|
281
|
+
content: source,
|
|
282
|
+
filePath: generatedSourceFile,
|
|
283
|
+
},
|
|
284
|
+
], check);
|
|
285
|
+
return {
|
|
286
|
+
check,
|
|
287
|
+
methodDescriptors,
|
|
288
|
+
source,
|
|
289
|
+
sourceFile: generatedSourceFile,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Projects one compiled `typia.llm` function schema into a JSON-friendly
|
|
294
|
+
* artifact record.
|
|
295
|
+
*
|
|
296
|
+
* @param functionSchema Function schema from a compiled `typia.llm.application(...)`.
|
|
297
|
+
* @returns JSON-friendly function artifact.
|
|
298
|
+
*/
|
|
299
|
+
export function projectTypiaLlmApplicationFunction(functionSchema) {
|
|
300
|
+
return {
|
|
301
|
+
description: functionSchema.description,
|
|
302
|
+
name: functionSchema.name,
|
|
303
|
+
output: cloneJsonValueIfDefined(functionSchema.output),
|
|
304
|
+
parameters: cloneJsonValue(functionSchema.parameters),
|
|
305
|
+
...(functionSchema.tags ? { tags: [...functionSchema.tags] } : {}),
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function cloneProjectedTypiaLlmFunctionArtifact(functionArtifact) {
|
|
309
|
+
return {
|
|
310
|
+
description: functionArtifact.description,
|
|
311
|
+
name: functionArtifact.name,
|
|
312
|
+
output: cloneJsonValueIfDefined(functionArtifact.output),
|
|
313
|
+
parameters: cloneJsonValue(functionArtifact.parameters),
|
|
314
|
+
...(functionArtifact.tags ? { tags: [...functionArtifact.tags] } : {}),
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Projects a compiled `typia.llm.application(...)` result into a JSON-friendly
|
|
319
|
+
* downstream adapter artifact.
|
|
320
|
+
*
|
|
321
|
+
* @param options Compiled application value and source metadata.
|
|
322
|
+
* @returns JSON-friendly application artifact.
|
|
323
|
+
*/
|
|
324
|
+
export function projectTypiaLlmApplicationArtifact({ application, generatedFrom, transformFunction, }) {
|
|
325
|
+
return {
|
|
326
|
+
functions: application.functions.map((functionSchema) => {
|
|
327
|
+
const functionArtifact = projectTypiaLlmApplicationFunction(functionSchema);
|
|
328
|
+
const transformedArtifact = transformFunction
|
|
329
|
+
? transformFunction(functionArtifact, functionSchema)
|
|
330
|
+
: functionArtifact;
|
|
331
|
+
return cloneProjectedTypiaLlmFunctionArtifact(transformedArtifact);
|
|
332
|
+
}),
|
|
333
|
+
generatedFrom: cloneJsonValue(generatedFrom),
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Projects a compiled `typia.llm.structuredOutput(...)` result into a
|
|
338
|
+
* JSON-friendly downstream adapter artifact.
|
|
339
|
+
*
|
|
340
|
+
* @param options Compiled structured-output value and source metadata.
|
|
341
|
+
* @returns JSON-friendly structured-output artifact.
|
|
342
|
+
*/
|
|
343
|
+
export function projectTypiaLlmStructuredOutputArtifact({ generatedFrom, structuredOutput, }) {
|
|
344
|
+
return {
|
|
345
|
+
generatedFrom: cloneJsonValue(generatedFrom),
|
|
346
|
+
parameters: cloneJsonValue(structuredOutput.parameters),
|
|
347
|
+
};
|
|
348
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { EndpointManifestDefinition, EndpointManifestEndpointDefinition } from '@wp-typia/block-runtime/metadata-core';
|
|
2
|
+
import { type EndpointAuthIntent, type EndpointWordPressAuthDefinition, type JsonSchemaDocument } from './schema-core.js';
|
|
3
|
+
import { type AbilitySpecCatalog } from './ability-spec.js';
|
|
4
|
+
export type { AbilityAnnotationSpec, AbilityCategorySpec, AbilityMcpProjectionSpec, AbilityMetaSpec, AbilitySpec, AbilitySpecCatalog, } from './ability-spec.js';
|
|
5
|
+
/**
|
|
6
|
+
* Represents one projected WordPress-native ability derived from an endpoint
|
|
7
|
+
* manifest plus an AbilitySpec definition.
|
|
8
|
+
*/
|
|
9
|
+
export interface ProjectedWordPressAbilityDefinition {
|
|
10
|
+
/** Normalized auth intent derived from the endpoint manifest. */
|
|
11
|
+
authIntent: EndpointAuthIntent;
|
|
12
|
+
/** Optional auth mode propagated from the manifest when present. */
|
|
13
|
+
authMode?: EndpointManifestEndpointDefinition['authMode'];
|
|
14
|
+
/** Shared category identifier resolved from the AbilitySpec catalog. */
|
|
15
|
+
category: string;
|
|
16
|
+
/** Human-readable summary shown to ability discovery consumers. */
|
|
17
|
+
description: string;
|
|
18
|
+
/** PHP callback that executes the ability. */
|
|
19
|
+
executeCallback: string;
|
|
20
|
+
/** Stable generated ability identifier. */
|
|
21
|
+
id: string;
|
|
22
|
+
/** Optional projected input schema, or null when no input exists. */
|
|
23
|
+
inputSchema: Record<string, unknown> | null;
|
|
24
|
+
/** Display label propagated from the AbilitySpec layer. */
|
|
25
|
+
label: string;
|
|
26
|
+
/** WordPress-owned metadata preserved in the projected document. */
|
|
27
|
+
meta: Record<string, unknown>;
|
|
28
|
+
/** HTTP method from the source endpoint manifest. */
|
|
29
|
+
method: EndpointManifestEndpointDefinition['method'];
|
|
30
|
+
/** Source operation identifier from the endpoint manifest. */
|
|
31
|
+
operationId: string;
|
|
32
|
+
/** Projected AI response schema shared by the document. */
|
|
33
|
+
outputSchema: Record<string, unknown>;
|
|
34
|
+
/** HTTP path from the source endpoint manifest. */
|
|
35
|
+
path: string;
|
|
36
|
+
/** PHP permission callback that gates the ability. */
|
|
37
|
+
permissionCallback: string;
|
|
38
|
+
/** Optional WordPress auth metadata preserved for downstream adapters. */
|
|
39
|
+
wordpressAuth?: EndpointWordPressAuthDefinition;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Bundles a single-category WordPress AI abilities document together with the
|
|
43
|
+
* metadata that describes how it was generated.
|
|
44
|
+
*/
|
|
45
|
+
export interface ProjectedWordPressAbilitiesDocument {
|
|
46
|
+
/** Ability definitions generated from the current manifest and AbilitySpec map. */
|
|
47
|
+
abilities: ProjectedWordPressAbilityDefinition[];
|
|
48
|
+
/** Shared category metadata for the generated document. */
|
|
49
|
+
category: {
|
|
50
|
+
id: string;
|
|
51
|
+
label: string;
|
|
52
|
+
};
|
|
53
|
+
/** Source metadata that points downstream consumers at the generated schema. */
|
|
54
|
+
generatedFrom: {
|
|
55
|
+
blockSlug: string;
|
|
56
|
+
responseSchemaPath: string;
|
|
57
|
+
schemaProfile: 'ai-structured-output';
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Carries the projected input schema plus endpoint metadata into an optional
|
|
62
|
+
* transform hook.
|
|
63
|
+
*/
|
|
64
|
+
export interface WordPressAiInputSchemaTransformContext {
|
|
65
|
+
/** Name of the input contract being transformed. */
|
|
66
|
+
contractName: string;
|
|
67
|
+
/** Source endpoint that requested the input schema. */
|
|
68
|
+
endpoint: EndpointManifestEndpointDefinition;
|
|
69
|
+
/** Already-projected AI-friendly input schema. */
|
|
70
|
+
schema: JsonSchemaDocument & Record<string, unknown>;
|
|
71
|
+
}
|
|
72
|
+
interface BuildWordPressAbilitiesDocumentOptions {
|
|
73
|
+
abilityCatalog: AbilitySpecCatalog;
|
|
74
|
+
buildAbilityId?: (operationId: string) => string;
|
|
75
|
+
generatedFrom: ProjectedWordPressAbilitiesDocument['generatedFrom'];
|
|
76
|
+
loadInputSchema?: (endpoint: EndpointManifestEndpointDefinition, contractName: string) => Promise<JsonSchemaDocument & Record<string, unknown>>;
|
|
77
|
+
manifest: EndpointManifestDefinition;
|
|
78
|
+
outputSchema: Record<string, unknown>;
|
|
79
|
+
transformInputSchema?: (context: WordPressAiInputSchemaTransformContext) => JsonSchemaDocument & Record<string, unknown>;
|
|
80
|
+
}
|
|
81
|
+
interface BuildWordPressAiArtifactsOptions extends Omit<BuildWordPressAbilitiesDocumentOptions, 'outputSchema'> {
|
|
82
|
+
responseSchema: JsonSchemaDocument & Record<string, unknown>;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Projects a canonical schema into the AI structured-output profile used by
|
|
86
|
+
* WordPress AI artifact generation.
|
|
87
|
+
*
|
|
88
|
+
* @param schema Canonical JSON Schema document from the manifest-owned source.
|
|
89
|
+
* @returns The projected AI-friendly schema document.
|
|
90
|
+
*/
|
|
91
|
+
export declare function projectWordPressAiSchema(schema: JsonSchemaDocument & Record<string, unknown>): JsonSchemaDocument & Record<string, unknown>;
|
|
92
|
+
/**
|
|
93
|
+
* Builds a WordPress abilities document from a manifest-first REST surface and
|
|
94
|
+
* a matching AbilitySpec catalog.
|
|
95
|
+
*
|
|
96
|
+
* Input schemas are loaded lazily per endpoint only when an input contract
|
|
97
|
+
* exists, and `transformInputSchema` runs after the schema has already been
|
|
98
|
+
* projected into the AI structured-output profile.
|
|
99
|
+
*
|
|
100
|
+
* @param options Manifest, ability catalog, and projected output schema inputs.
|
|
101
|
+
* @returns The generated WordPress abilities document.
|
|
102
|
+
* @throws When an endpoint is missing an AbilitySpec.
|
|
103
|
+
* @throws When categories are missing, inconsistent, or span multiple documents.
|
|
104
|
+
* @throws When an endpoint references a missing input contract or no loader was supplied.
|
|
105
|
+
*/
|
|
106
|
+
export declare function buildWordPressAbilitiesDocument({ abilityCatalog, buildAbilityId, generatedFrom, loadInputSchema, manifest, outputSchema, transformInputSchema, }: BuildWordPressAbilitiesDocumentOptions): Promise<ProjectedWordPressAbilitiesDocument>;
|
|
107
|
+
/**
|
|
108
|
+
* Builds the projected AI response schema together with its companion
|
|
109
|
+
* WordPress abilities document.
|
|
110
|
+
*
|
|
111
|
+
* All endpoints must share the same response contract and category so the
|
|
112
|
+
* generated artifacts stay aligned with one manifest-owned response surface.
|
|
113
|
+
*
|
|
114
|
+
* @param options Manifest, ability catalog, and response schema inputs.
|
|
115
|
+
* @returns The projected AI response schema and generated abilities document.
|
|
116
|
+
* @throws When the manifest has no endpoints.
|
|
117
|
+
* @throws When the shared response contract is missing or inconsistent.
|
|
118
|
+
*/
|
|
119
|
+
export declare function buildWordPressAiArtifacts({ abilityCatalog, buildAbilityId, generatedFrom, loadInputSchema, manifest, responseSchema, transformInputSchema, }: BuildWordPressAiArtifactsOptions): Promise<{
|
|
120
|
+
abilitiesDocument: ProjectedWordPressAbilitiesDocument;
|
|
121
|
+
aiResponseSchema: Record<string, unknown>;
|
|
122
|
+
}>;
|