@agentuity/cli 0.0.95 → 0.0.97
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/AGENTS.md +84 -0
- package/dist/auth.d.ts +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +8 -5
- package/dist/auth.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +190 -27
- package/dist/cli.js.map +1 -1
- package/dist/cmd/build/entry-generator.d.ts +20 -0
- package/dist/cmd/build/entry-generator.d.ts.map +1 -0
- package/dist/cmd/build/entry-generator.js +366 -0
- package/dist/cmd/build/entry-generator.js.map +1 -0
- package/dist/cmd/build/index.d.ts.map +1 -1
- package/dist/cmd/build/index.js +5 -23
- package/dist/cmd/build/index.js.map +1 -1
- package/dist/cmd/build/vite/agent-discovery.d.ts +33 -0
- package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -0
- package/dist/cmd/build/vite/agent-discovery.js +297 -0
- package/dist/cmd/build/vite/agent-discovery.js.map +1 -0
- package/dist/cmd/build/vite/browser-env-plugin.d.ts +9 -0
- package/dist/cmd/build/vite/browser-env-plugin.d.ts.map +1 -0
- package/dist/cmd/build/vite/browser-env-plugin.js +28 -0
- package/dist/cmd/build/vite/browser-env-plugin.js.map +1 -0
- package/dist/cmd/build/vite/bun-dev-server.d.ts +29 -0
- package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -0
- package/dist/cmd/build/vite/bun-dev-server.js +54 -0
- package/dist/cmd/build/vite/bun-dev-server.js.map +1 -0
- package/dist/cmd/build/vite/config-loader.d.ts +23 -0
- package/dist/cmd/build/vite/config-loader.d.ts.map +1 -0
- package/dist/cmd/build/vite/config-loader.js +50 -0
- package/dist/cmd/build/vite/config-loader.js.map +1 -0
- package/dist/cmd/build/vite/index.d.ts +26 -0
- package/dist/cmd/build/vite/index.d.ts.map +1 -0
- package/dist/cmd/build/vite/index.js +127 -0
- package/dist/cmd/build/vite/index.js.map +1 -0
- package/dist/cmd/build/vite/lifecycle-generator.d.ts +11 -0
- package/dist/cmd/build/vite/lifecycle-generator.d.ts.map +1 -0
- package/dist/cmd/build/vite/lifecycle-generator.js +35 -0
- package/dist/cmd/build/vite/lifecycle-generator.js.map +1 -0
- package/dist/cmd/build/vite/metadata-generator.d.ts +32 -0
- package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -0
- package/dist/cmd/build/vite/metadata-generator.js +489 -0
- package/dist/cmd/build/vite/metadata-generator.js.map +1 -0
- package/dist/cmd/build/vite/patch-plugin.d.ts +21 -0
- package/dist/cmd/build/vite/patch-plugin.d.ts.map +1 -0
- package/dist/cmd/build/vite/patch-plugin.js +70 -0
- package/dist/cmd/build/vite/patch-plugin.js.map +1 -0
- package/dist/cmd/build/vite/registry-generator.d.ts +19 -0
- package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -0
- package/dist/cmd/build/{route-registry.js → vite/registry-generator.js} +126 -48
- package/dist/cmd/build/vite/registry-generator.js.map +1 -0
- package/dist/cmd/build/vite/route-discovery.d.ts +58 -0
- package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -0
- package/dist/cmd/build/vite/route-discovery.js +125 -0
- package/dist/cmd/build/vite/route-discovery.js.map +1 -0
- package/dist/cmd/build/vite/server-bundler.d.ts +16 -0
- package/dist/cmd/build/vite/server-bundler.d.ts.map +1 -0
- package/dist/cmd/build/vite/server-bundler.js +194 -0
- package/dist/cmd/build/vite/server-bundler.js.map +1 -0
- package/dist/cmd/build/vite/vite-asset-server-config.d.ts +19 -0
- package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -0
- package/dist/cmd/build/vite/vite-asset-server-config.js +105 -0
- package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -0
- package/dist/cmd/build/vite/vite-asset-server.d.ts +23 -0
- package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -0
- package/dist/cmd/build/vite/vite-asset-server.js +41 -0
- package/dist/cmd/build/vite/vite-asset-server.js.map +1 -0
- package/dist/cmd/build/vite/vite-builder.d.ts +44 -0
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -0
- package/dist/cmd/build/vite/vite-builder.js +234 -0
- package/dist/cmd/build/vite/vite-builder.js.map +1 -0
- package/dist/cmd/build/vite/workbench-generator.d.ts +10 -0
- package/dist/cmd/build/vite/workbench-generator.d.ts.map +1 -0
- package/dist/cmd/build/vite/workbench-generator.js +135 -0
- package/dist/cmd/build/vite/workbench-generator.js.map +1 -0
- package/dist/cmd/build/vite-bundler.d.ts +23 -0
- package/dist/cmd/build/vite-bundler.d.ts.map +1 -0
- package/dist/cmd/build/vite-bundler.js +79 -0
- package/dist/cmd/build/vite-bundler.js.map +1 -0
- package/dist/cmd/cloud/agent/get.d.ts.map +1 -1
- package/dist/cmd/cloud/agent/get.js +1 -0
- package/dist/cmd/cloud/agent/get.js.map +1 -1
- package/dist/cmd/cloud/agent/list.d.ts.map +1 -1
- package/dist/cmd/cloud/agent/list.js +1 -0
- package/dist/cmd/cloud/agent/list.js.map +1 -1
- package/dist/cmd/cloud/db/get.d.ts.map +1 -1
- package/dist/cmd/cloud/db/get.js +1 -0
- package/dist/cmd/cloud/db/get.js.map +1 -1
- package/dist/cmd/cloud/db/list.d.ts.map +1 -1
- package/dist/cmd/cloud/db/list.js +1 -0
- package/dist/cmd/cloud/db/list.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +152 -128
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/deployment/list.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/list.js +4 -0
- package/dist/cmd/cloud/deployment/list.js.map +1 -1
- package/dist/cmd/cloud/env/list.d.ts.map +1 -1
- package/dist/cmd/cloud/env/list.js +1 -0
- package/dist/cmd/cloud/env/list.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/get.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/get.js +1 -0
- package/dist/cmd/cloud/keyvalue/get.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/keys.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/keys.js +1 -0
- package/dist/cmd/cloud/keyvalue/keys.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/list-namespaces.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/list-namespaces.js +1 -0
- package/dist/cmd/cloud/keyvalue/list-namespaces.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/stats.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/stats.js +1 -0
- package/dist/cmd/cloud/keyvalue/stats.js.map +1 -1
- package/dist/cmd/cloud/secret/list.d.ts.map +1 -1
- package/dist/cmd/cloud/secret/list.js +1 -0
- package/dist/cmd/cloud/secret/list.js.map +1 -1
- package/dist/cmd/cloud/session/list.d.ts.map +1 -1
- package/dist/cmd/cloud/session/list.js +4 -0
- package/dist/cmd/cloud/session/list.js.map +1 -1
- package/dist/cmd/cloud/storage/get.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/get.js +1 -0
- package/dist/cmd/cloud/storage/get.js.map +1 -1
- package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/list.js +3 -0
- package/dist/cmd/cloud/storage/list.js.map +1 -1
- package/dist/cmd/cloud/stream/get.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/get.js +1 -0
- package/dist/cmd/cloud/stream/get.js.map +1 -1
- package/dist/cmd/cloud/stream/list.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/list.js +1 -0
- package/dist/cmd/cloud/stream/list.js.map +1 -1
- package/dist/cmd/cloud/vector/get.d.ts.map +1 -1
- package/dist/cmd/cloud/vector/get.js +1 -0
- package/dist/cmd/cloud/vector/get.js.map +1 -1
- package/dist/cmd/cloud/vector/search.d.ts.map +1 -1
- package/dist/cmd/cloud/vector/search.js +1 -0
- package/dist/cmd/cloud/vector/search.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +289 -758
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/dev/sync.d.ts +1 -1
- package/dist/cmd/dev/sync.d.ts.map +1 -1
- package/dist/cmd/dev/sync.js +3 -0
- package/dist/cmd/dev/sync.js.map +1 -1
- package/dist/cmd/profile/show.d.ts.map +1 -1
- package/dist/cmd/profile/show.js +3 -4
- package/dist/cmd/profile/show.js.map +1 -1
- package/dist/cmd/project/create.d.ts.map +1 -1
- package/dist/cmd/project/create.js +3 -4
- package/dist/cmd/project/create.js.map +1 -1
- package/dist/cmd/project/list.d.ts.map +1 -1
- package/dist/cmd/project/list.js +1 -0
- package/dist/cmd/project/list.js.map +1 -1
- package/dist/cmd/project/show.d.ts.map +1 -1
- package/dist/cmd/project/show.js +1 -0
- package/dist/cmd/project/show.js.map +1 -1
- package/dist/cmd/upgrade/index.d.ts.map +1 -1
- package/dist/cmd/upgrade/index.js +43 -7
- package/dist/cmd/upgrade/index.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +29 -11
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime-bootstrap.d.ts +3 -2
- package/dist/runtime-bootstrap.d.ts.map +1 -1
- package/dist/runtime-bootstrap.js +7 -2
- package/dist/runtime-bootstrap.js.map +1 -1
- package/dist/schemas/deploy.d.ts +1 -1
- package/dist/types.d.ts +40 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/bun-version-checker.d.ts +11 -0
- package/dist/utils/bun-version-checker.d.ts.map +1 -0
- package/dist/utils/bun-version-checker.js +56 -0
- package/dist/utils/bun-version-checker.js.map +1 -0
- package/dist/version-check.d.ts.map +1 -1
- package/dist/version-check.js +5 -2
- package/dist/version-check.js.map +1 -1
- package/package.json +11 -3
- package/src/auth.ts +9 -5
- package/src/cli.ts +228 -29
- package/src/cmd/build/entry-generator.ts +404 -0
- package/src/cmd/build/index.ts +7 -28
- package/src/cmd/build/vite/agent-discovery.ts +467 -0
- package/src/cmd/build/vite/browser-env-plugin.ts +34 -0
- package/src/cmd/build/vite/bun-dev-server.ts +78 -0
- package/src/cmd/build/vite/config-loader.ts +70 -0
- package/src/cmd/build/vite/index.ts +166 -0
- package/src/cmd/build/vite/lifecycle-generator.ts +43 -0
- package/src/cmd/build/vite/metadata-generator.ts +602 -0
- package/src/cmd/build/vite/patch-plugin.ts +88 -0
- package/src/cmd/build/vite/registry-generator.ts +288 -0
- package/src/cmd/build/vite/route-discovery.ts +186 -0
- package/src/cmd/build/vite/server-bundler.ts +258 -0
- package/src/cmd/build/vite/vite-asset-server-config.ts +134 -0
- package/src/cmd/build/vite/vite-asset-server.ts +66 -0
- package/src/cmd/build/vite/vite-builder.ts +288 -0
- package/src/cmd/build/vite/workbench-generator.ts +152 -0
- package/src/cmd/build/vite-bundler.ts +110 -0
- package/src/cmd/cloud/agent/get.ts +2 -0
- package/src/cmd/cloud/agent/list.ts +1 -0
- package/src/cmd/cloud/db/get.ts +1 -0
- package/src/cmd/cloud/db/list.ts +1 -0
- package/src/cmd/cloud/deploy.ts +175 -144
- package/src/cmd/cloud/deployment/list.ts +4 -0
- package/src/cmd/cloud/env/list.ts +1 -0
- package/src/cmd/cloud/keyvalue/get.ts +1 -0
- package/src/cmd/cloud/keyvalue/keys.ts +1 -0
- package/src/cmd/cloud/keyvalue/list-namespaces.ts +1 -0
- package/src/cmd/cloud/keyvalue/stats.ts +2 -0
- package/src/cmd/cloud/secret/list.ts +1 -0
- package/src/cmd/cloud/session/list.ts +4 -0
- package/src/cmd/cloud/storage/get.ts +1 -0
- package/src/cmd/cloud/storage/list.ts +4 -0
- package/src/cmd/cloud/stream/get.ts +1 -0
- package/src/cmd/cloud/stream/list.ts +1 -0
- package/src/cmd/cloud/vector/get.ts +1 -0
- package/src/cmd/cloud/vector/search.ts +1 -0
- package/src/cmd/dev/index.ts +319 -921
- package/src/cmd/dev/sync.ts +5 -1
- package/src/cmd/profile/show.ts +3 -4
- package/src/cmd/project/create.ts +3 -4
- package/src/cmd/project/list.ts +1 -0
- package/src/cmd/project/show.ts +1 -0
- package/src/cmd/upgrade/index.ts +52 -8
- package/src/config.ts +31 -11
- package/src/index.ts +2 -0
- package/src/runtime-bootstrap.ts +8 -2
- package/src/types.ts +48 -1
- package/src/utils/bun-version-checker.ts +70 -0
- package/src/version-check.ts +6 -2
- package/dist/cmd/build/bundler.d.ts +0 -28
- package/dist/cmd/build/bundler.d.ts.map +0 -1
- package/dist/cmd/build/bundler.js +0 -800
- package/dist/cmd/build/bundler.js.map +0 -1
- package/dist/cmd/build/config-loader.d.ts +0 -16
- package/dist/cmd/build/config-loader.d.ts.map +0 -1
- package/dist/cmd/build/config-loader.js +0 -227
- package/dist/cmd/build/config-loader.js.map +0 -1
- package/dist/cmd/build/file.d.ts +0 -2
- package/dist/cmd/build/file.d.ts.map +0 -1
- package/dist/cmd/build/file.js +0 -10
- package/dist/cmd/build/file.js.map +0 -1
- package/dist/cmd/build/fix-duplicate-exports.d.ts +0 -2
- package/dist/cmd/build/fix-duplicate-exports.d.ts.map +0 -1
- package/dist/cmd/build/fix-duplicate-exports.js +0 -170
- package/dist/cmd/build/fix-duplicate-exports.js.map +0 -1
- package/dist/cmd/build/plugin.d.ts +0 -6
- package/dist/cmd/build/plugin.d.ts.map +0 -1
- package/dist/cmd/build/plugin.js +0 -645
- package/dist/cmd/build/plugin.js.map +0 -1
- package/dist/cmd/build/route-discovery.d.ts +0 -54
- package/dist/cmd/build/route-discovery.d.ts.map +0 -1
- package/dist/cmd/build/route-discovery.js +0 -148
- package/dist/cmd/build/route-discovery.js.map +0 -1
- package/dist/cmd/build/route-registry.d.ts +0 -38
- package/dist/cmd/build/route-registry.d.ts.map +0 -1
- package/dist/cmd/build/route-registry.js.map +0 -1
- package/src/cmd/build/bundler.ts +0 -965
- package/src/cmd/build/config-loader.ts +0 -268
- package/src/cmd/build/file.ts +0 -10
- package/src/cmd/build/fix-duplicate-exports.ts +0 -207
- package/src/cmd/build/plugin.ts +0 -782
- package/src/cmd/build/route-discovery.ts +0 -202
- package/src/cmd/build/route-registry.ts +0 -222
package/src/cmd/build/plugin.ts
DELETED
|
@@ -1,782 +0,0 @@
|
|
|
1
|
-
import type { BunPlugin } from 'bun';
|
|
2
|
-
import { dirname, join, resolve } from 'node:path';
|
|
3
|
-
import { existsSync, writeFileSync, mkdirSync, unlinkSync } from 'node:fs';
|
|
4
|
-
import type { BuildMetadata } from '@agentuity/server';
|
|
5
|
-
import {
|
|
6
|
-
parseAgentMetadata,
|
|
7
|
-
parseEvalMetadata,
|
|
8
|
-
parseRoute,
|
|
9
|
-
analyzeWorkbench,
|
|
10
|
-
generateLifecycleTypes,
|
|
11
|
-
findCreateAppEndPosition,
|
|
12
|
-
} from './ast';
|
|
13
|
-
import { StructuredError, type WorkbenchConfig } from '@agentuity/core';
|
|
14
|
-
import { applyPatch, generatePatches } from './patch';
|
|
15
|
-
import { createLogger } from '@agentuity/server';
|
|
16
|
-
import type { LogLevel } from '../../types';
|
|
17
|
-
import { toCamelCase, toPascalCase } from '../../utils/string';
|
|
18
|
-
import { generateRouteRegistry, type RouteInfo } from './route-registry';
|
|
19
|
-
import { discoverRouteFiles } from './route-discovery';
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Setup lifecycle types by analyzing app.ts for setup() function
|
|
23
|
-
*/
|
|
24
|
-
async function setupLifecycleTypes(
|
|
25
|
-
rootDir: string,
|
|
26
|
-
outDir: string,
|
|
27
|
-
srcDir: string,
|
|
28
|
-
logger: ReturnType<typeof createLogger>
|
|
29
|
-
): Promise<boolean> {
|
|
30
|
-
// Look for app.ts in both root and src directories
|
|
31
|
-
const rootAppFile = join(dirname(srcDir), 'app.ts');
|
|
32
|
-
const srcAppFile = join(srcDir, 'app.ts');
|
|
33
|
-
|
|
34
|
-
let appFile = '';
|
|
35
|
-
if (await Bun.file(rootAppFile).exists()) {
|
|
36
|
-
appFile = rootAppFile;
|
|
37
|
-
} else if (await Bun.file(srcAppFile).exists()) {
|
|
38
|
-
appFile = srcAppFile;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (!appFile || !(await Bun.file(appFile).exists())) {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
return await generateLifecycleTypes(rootDir, outDir, appFile);
|
|
47
|
-
} catch (error) {
|
|
48
|
-
logger.fatal('Failed to generate lifecycle types:', error);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Setup workbench configuration by analyzing app.ts file
|
|
54
|
-
*/
|
|
55
|
-
async function setupWorkbench(srcDir: string): Promise<WorkbenchConfig | null> {
|
|
56
|
-
// Look for app.ts in both root and src directories
|
|
57
|
-
const rootAppFile = join(dirname(srcDir), 'app.ts');
|
|
58
|
-
const srcAppFile = join(srcDir, 'app.ts');
|
|
59
|
-
|
|
60
|
-
let appFile = '';
|
|
61
|
-
if (await Bun.file(rootAppFile).exists()) {
|
|
62
|
-
appFile = rootAppFile;
|
|
63
|
-
} else if (await Bun.file(srcAppFile).exists()) {
|
|
64
|
-
appFile = srcAppFile;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (!appFile || !(await Bun.file(appFile).exists())) {
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const appContent = await Bun.file(appFile).text();
|
|
72
|
-
const analysis = analyzeWorkbench(appContent);
|
|
73
|
-
|
|
74
|
-
if (!analysis.hasWorkbench) {
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const workbenchConfig = analysis.config;
|
|
79
|
-
|
|
80
|
-
return workbenchConfig;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const AgentIdentifierCollisionError = StructuredError('AgentIdentifierCollisionError');
|
|
84
|
-
|
|
85
|
-
function generateAgentRegistry(srcDir: string, agentInfo: Array<Record<string, string>>) {
|
|
86
|
-
// Detect naming collisions in generated identifiers
|
|
87
|
-
const generatedNames = new Set<string>();
|
|
88
|
-
const collisions: string[] = [];
|
|
89
|
-
|
|
90
|
-
for (const agent of agentInfo) {
|
|
91
|
-
const camelName = toCamelCase(agent.name);
|
|
92
|
-
|
|
93
|
-
if (generatedNames.has(camelName)) {
|
|
94
|
-
collisions.push(`Identifier collision detected: "${camelName}" (from "${agent.name}")`);
|
|
95
|
-
}
|
|
96
|
-
generatedNames.add(camelName);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (collisions.length > 0) {
|
|
100
|
-
throw new AgentIdentifierCollisionError({
|
|
101
|
-
message:
|
|
102
|
-
`Agent identifier naming collisions detected:\n${collisions.join('\n')}\n\n` +
|
|
103
|
-
`This occurs when different agent names produce the same camelCase identifier.\n` +
|
|
104
|
-
`Please rename your agents to avoid this collision.`,
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Generate imports for all agents
|
|
109
|
-
// Registry is now in .agentuity/, so imports need to go up one level and into src/
|
|
110
|
-
const imports = agentInfo
|
|
111
|
-
.map(({ name, path }) => {
|
|
112
|
-
const camelName = toCamelCase(name);
|
|
113
|
-
const relativePath = path.replace(/^\.\/agent\//, '../src/agent/');
|
|
114
|
-
return `import ${camelName}Agent from '${relativePath}';`;
|
|
115
|
-
})
|
|
116
|
-
.join('\n');
|
|
117
|
-
|
|
118
|
-
// Generate flat registry structure (no subagents)
|
|
119
|
-
const registry = agentInfo
|
|
120
|
-
.map(({ name }) => {
|
|
121
|
-
const camelName = toCamelCase(name);
|
|
122
|
-
return ` ${camelName}: ${camelName}Agent,`;
|
|
123
|
-
})
|
|
124
|
-
.join('\n');
|
|
125
|
-
|
|
126
|
-
// Generate type exports for all agents
|
|
127
|
-
const typeExports = agentInfo
|
|
128
|
-
.map(({ name }) => {
|
|
129
|
-
const camelName = toCamelCase(name);
|
|
130
|
-
const pascalName = toPascalCase(name);
|
|
131
|
-
return `export type ${pascalName}AgentRunner = AgentRunner<typeof ${camelName}Agent['inputSchema'], typeof ${camelName}Agent['outputSchema'], typeof ${camelName}Agent['stream'] extends true ? true : false>;`;
|
|
132
|
-
})
|
|
133
|
-
.join('\n');
|
|
134
|
-
|
|
135
|
-
// Generate flat agent type definitions for AgentRegistry interface augmentation
|
|
136
|
-
const runtimeAgentTypes = agentInfo
|
|
137
|
-
.map(({ name }) => {
|
|
138
|
-
const camelName = toCamelCase(name);
|
|
139
|
-
return ` ${camelName}: AgentRunner<typeof ${camelName}Agent['inputSchema'], typeof ${camelName}Agent['outputSchema'], typeof ${camelName}Agent['stream'] extends true ? true : false>;`;
|
|
140
|
-
})
|
|
141
|
-
.join('\n');
|
|
142
|
-
|
|
143
|
-
const generatedContent = `/// <reference types="hono" />
|
|
144
|
-
// Auto-generated by Agentuity - do not edit manually
|
|
145
|
-
${imports}
|
|
146
|
-
import type { AgentRunner, Logger } from '@agentuity/runtime';
|
|
147
|
-
import type { KeyValueStorage, StreamStorage, VectorStorage } from '@agentuity/core';
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Registry of all agents in this application.
|
|
151
|
-
* Provides strongly-typed access to agent metadata and runner functions.
|
|
152
|
-
* Auto-generated from your agent files during build.
|
|
153
|
-
*/
|
|
154
|
-
export const agentRegistry = {
|
|
155
|
-
${registry}
|
|
156
|
-
} as const;
|
|
157
|
-
|
|
158
|
-
// Local type aliases for Hono augmentation
|
|
159
|
-
type LocalAgentName = keyof typeof agentRegistry;
|
|
160
|
-
type LocalAgentRegistry = typeof agentRegistry;
|
|
161
|
-
|
|
162
|
-
// Typed runners for each agent
|
|
163
|
-
${typeExports}
|
|
164
|
-
|
|
165
|
-
// Augment @agentuity/runtime types with strongly-typed agents from this project
|
|
166
|
-
declare module "@agentuity/runtime" {
|
|
167
|
-
// Augment the AgentRegistry interface with project-specific strongly-typed agents
|
|
168
|
-
export interface AgentRegistry {
|
|
169
|
-
${runtimeAgentTypes}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// NOTE: Hono Context properties are accessed via c.var (e.g., c.var.logger, c.var.kv)
|
|
174
|
-
// The Variables interface in @agentuity/runtime defines all available context properties
|
|
175
|
-
`;
|
|
176
|
-
|
|
177
|
-
const projectRoot = join(srcDir, '..');
|
|
178
|
-
const agentuityDir = join(projectRoot, '.agentuity');
|
|
179
|
-
const registryPath = join(agentuityDir, 'registry.generated.ts');
|
|
180
|
-
|
|
181
|
-
const agentsDir = join(srcDir, 'agent');
|
|
182
|
-
const legacyTypesPath = join(agentsDir, 'types.generated.d.ts');
|
|
183
|
-
|
|
184
|
-
// Ensure .agentuity directory exists
|
|
185
|
-
if (!existsSync(agentuityDir)) {
|
|
186
|
-
mkdirSync(agentuityDir, { recursive: true });
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
writeFileSync(registryPath, generatedContent, 'utf-8');
|
|
190
|
-
|
|
191
|
-
// Remove legacy types.generated.d.ts if it exists (now consolidated into registry.generated.ts)
|
|
192
|
-
if (existsSync(legacyTypesPath)) {
|
|
193
|
-
unlinkSync(legacyTypesPath);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
let metadata: Partial<BuildMetadata>;
|
|
198
|
-
|
|
199
|
-
export function getBuildMetadata(): Partial<BuildMetadata> {
|
|
200
|
-
return metadata;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const AgentNameDuplicateError = StructuredError('AgentNameDuplicateError');
|
|
204
|
-
const MetadataPropertyMissingError = StructuredError('MetadataPropertyMissingError')<{
|
|
205
|
-
name: string;
|
|
206
|
-
}>();
|
|
207
|
-
|
|
208
|
-
const AgentuityBundler: BunPlugin = {
|
|
209
|
-
name: 'Agentuity Bundler',
|
|
210
|
-
setup(build) {
|
|
211
|
-
const rootDir = resolve(build.config.root ?? '.');
|
|
212
|
-
const srcDir = join(rootDir, 'src');
|
|
213
|
-
const outDir = build.config.outdir;
|
|
214
|
-
if (!outDir) {
|
|
215
|
-
throw new Error('missing outdir must be set');
|
|
216
|
-
}
|
|
217
|
-
const projectId = build.config.define?.['process.env.AGENTUITY_CLOUD_PROJECT_ID']
|
|
218
|
-
? JSON.parse(build.config.define['process.env.AGENTUITY_CLOUD_PROJECT_ID'])
|
|
219
|
-
: '';
|
|
220
|
-
const deploymentId = build.config.define?.['process.env.AGENTUITY_CLOUD_DEPLOYMENT_ID']
|
|
221
|
-
? JSON.parse(build.config.define['process.env.AGENTUITY_CLOUD_DEPLOYMENT_ID'])
|
|
222
|
-
: '';
|
|
223
|
-
const isDevMode =
|
|
224
|
-
(build.config.define?.['process.env.NODE_ENV']
|
|
225
|
-
? JSON.parse(build.config.define['process.env.NODE_ENV'])
|
|
226
|
-
: 'production') === 'development';
|
|
227
|
-
const agentInfo: Array<Record<string, string>> = [];
|
|
228
|
-
const agentMetadata: Map<string, Map<string, string>> = new Map<
|
|
229
|
-
string,
|
|
230
|
-
Map<string, string>
|
|
231
|
-
>();
|
|
232
|
-
const transpiler = new Bun.Transpiler({ loader: 'ts', target: 'bun' });
|
|
233
|
-
|
|
234
|
-
// Scan ALL .ts files in src/agent directory for agents
|
|
235
|
-
build.onLoad({ filter: /\/agent\/.*\.ts$/, namespace: 'file' }, async (args) => {
|
|
236
|
-
let newsource = await Bun.file(args.path).text();
|
|
237
|
-
if (args.path.startsWith(srcDir)) {
|
|
238
|
-
const contents = transpiler.transformSync(newsource);
|
|
239
|
-
|
|
240
|
-
// Check if this is an eval file (eval.ts)
|
|
241
|
-
if (args.path.endsWith('/eval.ts')) {
|
|
242
|
-
// parseEvalMetadata will find the agent from the import statement
|
|
243
|
-
const [ns] = await parseEvalMetadata(
|
|
244
|
-
rootDir,
|
|
245
|
-
args.path,
|
|
246
|
-
contents,
|
|
247
|
-
projectId,
|
|
248
|
-
deploymentId,
|
|
249
|
-
undefined, // No agentId - will be resolved from import
|
|
250
|
-
agentMetadata
|
|
251
|
-
);
|
|
252
|
-
newsource = ns;
|
|
253
|
-
} else {
|
|
254
|
-
// Handle regular agent files
|
|
255
|
-
const result = await parseAgentMetadata(
|
|
256
|
-
rootDir,
|
|
257
|
-
args.path,
|
|
258
|
-
contents,
|
|
259
|
-
projectId,
|
|
260
|
-
deploymentId
|
|
261
|
-
);
|
|
262
|
-
|
|
263
|
-
// Skip files that don't have a createAgent export
|
|
264
|
-
if (result === undefined) {
|
|
265
|
-
return {
|
|
266
|
-
contents: newsource,
|
|
267
|
-
loader: 'ts',
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const [ns, md] = result;
|
|
272
|
-
newsource = ns;
|
|
273
|
-
|
|
274
|
-
// Only process files that actually export an agent
|
|
275
|
-
if (md.has('name')) {
|
|
276
|
-
const newAgentName = md.get('name');
|
|
277
|
-
for (const [, kv] of agentMetadata) {
|
|
278
|
-
const found = kv.get('name');
|
|
279
|
-
if (newAgentName === found) {
|
|
280
|
-
throw new AgentNameDuplicateError({
|
|
281
|
-
message: `The agent in ${kv.get('filename')} and the agent in ${md.get('filename')} have the same name (${found}). Agent Names must be unique within a project.`,
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
agentMetadata.set(md.get('name')!, md);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
return {
|
|
291
|
-
contents: newsource,
|
|
292
|
-
loader: 'ts',
|
|
293
|
-
};
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
const patches = generatePatches();
|
|
297
|
-
for (const [, patch] of patches) {
|
|
298
|
-
let modulePath = join('node_modules', patch.module, '.*');
|
|
299
|
-
if (patch.filename) {
|
|
300
|
-
modulePath = join('node_modules', patch.module, patch.filename + '.*');
|
|
301
|
-
}
|
|
302
|
-
build.onLoad(
|
|
303
|
-
{
|
|
304
|
-
filter: new RegExp(modulePath),
|
|
305
|
-
namespace: 'file',
|
|
306
|
-
},
|
|
307
|
-
async (args) => {
|
|
308
|
-
if (build.config.target !== 'bun') {
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
const [contents, loader] = await applyPatch(args.path, patch);
|
|
312
|
-
return {
|
|
313
|
-
contents,
|
|
314
|
-
loader,
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
build.onLoad(
|
|
321
|
-
{
|
|
322
|
-
filter: new RegExp(join(rootDir, 'app.ts')),
|
|
323
|
-
namespace: 'file',
|
|
324
|
-
},
|
|
325
|
-
async (args) => {
|
|
326
|
-
const logger = createLogger((process.env.AGENTUITY_LOG_LEVEL as LogLevel) || 'info');
|
|
327
|
-
if (build.config.target !== 'bun') {
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
await args.defer();
|
|
331
|
-
|
|
332
|
-
const inserts: string[] = [];
|
|
333
|
-
|
|
334
|
-
const indexFile = join(srcDir, 'web', 'index.html');
|
|
335
|
-
|
|
336
|
-
// Setup workbench configuration - evaluate fresh each time during builds
|
|
337
|
-
const workbenchConfig = await setupWorkbench(srcDir);
|
|
338
|
-
|
|
339
|
-
// Store web routes for later (must be registered AFTER API routes)
|
|
340
|
-
let webRoutesInsert: string | null = null;
|
|
341
|
-
|
|
342
|
-
if (existsSync(indexFile)) {
|
|
343
|
-
webRoutesInsert = `import { serveStatic } from 'hono/bun';
|
|
344
|
-
import { getRouter, registerDevModeRoutes } from '@agentuity/runtime';
|
|
345
|
-
import { readFileSync, existsSync } from 'node:fs';
|
|
346
|
-
|
|
347
|
-
(() => {
|
|
348
|
-
const router = getRouter()!;
|
|
349
|
-
|
|
350
|
-
// Setup workbench routes if workbench was bundled
|
|
351
|
-
const workbenchIndexPath = import.meta.dir + '/workbench/index.html';
|
|
352
|
-
if (existsSync(workbenchIndexPath)) {
|
|
353
|
-
let workbenchIndex = readFileSync(workbenchIndexPath, 'utf-8');
|
|
354
|
-
|
|
355
|
-
// Always serve assets at /workbench/* regardless of HTML route
|
|
356
|
-
const workbenchStatic = serveStatic({ root: import.meta.dir + '/workbench' });
|
|
357
|
-
router.get('/workbench/*', workbenchStatic);
|
|
358
|
-
|
|
359
|
-
// Use the workbench config determined at build time
|
|
360
|
-
const route = ${JSON.stringify(workbenchConfig?.route || '/workbench')};
|
|
361
|
-
|
|
362
|
-
// If using custom route, update HTML to point to absolute /workbench/ paths
|
|
363
|
-
if (route !== '/workbench') {
|
|
364
|
-
workbenchIndex = workbenchIndex.replace(new RegExp('src="\\\\.\\\\/workbench\\\\/', 'g'), 'src="/workbench/');
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Serve HTML at the configured route
|
|
368
|
-
router.get(route, (c) => c.html(workbenchIndex));
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
let index = readFileSync(import.meta.dir + '/web/index.html', 'utf-8');
|
|
372
|
-
if (${isDevMode}) {
|
|
373
|
-
const end = index.lastIndexOf('</html>');
|
|
374
|
-
const html = registerDevModeRoutes(router);
|
|
375
|
-
if (end > 0) {
|
|
376
|
-
index = index.substring(0,end) + html + index.substring(end);
|
|
377
|
-
} else {
|
|
378
|
-
index += html;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
// make paths absolute
|
|
382
|
-
index = index.replaceAll('./web/', '/web/');
|
|
383
|
-
const webstatic = serveStatic({ root: import.meta.dir + '/web' });
|
|
384
|
-
// In dev mode, serve from source; in prod, serve from build output
|
|
385
|
-
const publicRoot = ${isDevMode} ? ${JSON.stringify(join(srcDir, 'web', 'public'))} : import.meta.dir + '/web/public';
|
|
386
|
-
const publicstatic = serveStatic({ root: publicRoot, rewriteRequestPath: (path) => path });
|
|
387
|
-
router.get('/', (c) => c.html(index));
|
|
388
|
-
router.get('/web/chunk/*', webstatic);
|
|
389
|
-
router.get('/web/asset/*', webstatic);
|
|
390
|
-
// Serve public assets at root (e.g., /favicon.ico) - must be last
|
|
391
|
-
router.get('/*', async (c, next) => {
|
|
392
|
-
const path = c.req.path;
|
|
393
|
-
// Skip API routes - let them 404 naturally
|
|
394
|
-
if (path === '/api' || path.startsWith('/api/')) {
|
|
395
|
-
return c.notFound();
|
|
396
|
-
}
|
|
397
|
-
// Prevent directory traversal attacks
|
|
398
|
-
if (path.includes('..') || path.includes('%2e%2e')) {
|
|
399
|
-
return c.notFound();
|
|
400
|
-
}
|
|
401
|
-
// Don't catch workbench routes (already handled above)
|
|
402
|
-
if (path.startsWith('/workbench')) {
|
|
403
|
-
return c.notFound();
|
|
404
|
-
}
|
|
405
|
-
// serve default for any path not explicitly matched
|
|
406
|
-
return c.html(index);
|
|
407
|
-
});
|
|
408
|
-
})();`;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// Build agentInfo from all discovered agents and track directories
|
|
412
|
-
const agentDirs = new Set<string>();
|
|
413
|
-
for (const [_identifier, md] of agentMetadata) {
|
|
414
|
-
// md.get('filename') can be either absolute or relative to rootDir
|
|
415
|
-
const filename = md.get('filename')!;
|
|
416
|
-
const absolutePath = filename.startsWith('/') ? filename : join(rootDir, filename);
|
|
417
|
-
|
|
418
|
-
// Track which directories have agents
|
|
419
|
-
const dir = dirname(absolutePath);
|
|
420
|
-
agentDirs.add(dir);
|
|
421
|
-
|
|
422
|
-
// Convert to path relative to srcDir
|
|
423
|
-
// e.g., /path/to/src/agent/my-agent.ts -> ./agent/my-agent
|
|
424
|
-
const agentPath = absolutePath.replace(srcDir, '.').replace('.ts', '');
|
|
425
|
-
|
|
426
|
-
const agentDetail: Record<string, string> = {
|
|
427
|
-
name: md.get('name')!,
|
|
428
|
-
id: md.get('id')!,
|
|
429
|
-
path: agentPath,
|
|
430
|
-
filename: absolutePath,
|
|
431
|
-
description: md.get('description') ?? '',
|
|
432
|
-
agentId: md.get('agentId')!,
|
|
433
|
-
};
|
|
434
|
-
agentInfo.push(agentDetail);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// Validate that all directories in src/agent have at least one agent
|
|
438
|
-
const agentBaseDir = join(srcDir, 'agent');
|
|
439
|
-
if (existsSync(agentBaseDir)) {
|
|
440
|
-
const { readdirSync, statSync } = await import('node:fs');
|
|
441
|
-
const subdirs = readdirSync(agentBaseDir).filter((name) => {
|
|
442
|
-
const fullPath = join(agentBaseDir, name);
|
|
443
|
-
return statSync(fullPath).isDirectory();
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
for (const subdir of subdirs) {
|
|
447
|
-
const fullPath = join(agentBaseDir, subdir);
|
|
448
|
-
// Check if this directory or any subdirectory contains agents
|
|
449
|
-
const hasAgentInTree = Array.from(agentDirs).some((agentDir) =>
|
|
450
|
-
agentDir.startsWith(fullPath)
|
|
451
|
-
);
|
|
452
|
-
if (!hasAgentInTree) {
|
|
453
|
-
throw new Error(
|
|
454
|
-
`Directory ${subdir} in src/agent must contain at least one agent (a file with a createAgent export)`
|
|
455
|
-
);
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
// Only generate registry if there are agents
|
|
461
|
-
// Note: We don't import the registry here because:
|
|
462
|
-
// 1. Evals are already imported when agents are registered (see line 421-422)
|
|
463
|
-
// 2. The registry is for type definitions only, not runtime execution
|
|
464
|
-
// 3. Importing it causes bundler resolution issues since it's generated during build
|
|
465
|
-
generateAgentRegistry(srcDir, agentInfo);
|
|
466
|
-
|
|
467
|
-
// Generate lifecycle types if setup() is present in app.ts
|
|
468
|
-
await setupLifecycleTypes(rootDir, outDir, srcDir, logger);
|
|
469
|
-
|
|
470
|
-
// Parse routes from src/api directory
|
|
471
|
-
const apiRoutesMetadata: BuildMetadata['routes'] = [];
|
|
472
|
-
const routeInfoList: RouteInfo[] = [];
|
|
473
|
-
const apiDir = join(srcDir, 'api');
|
|
474
|
-
// Track subdirectory routes for auto-mounting
|
|
475
|
-
const subRouteInserts: string[] = [];
|
|
476
|
-
if (existsSync(apiDir)) {
|
|
477
|
-
// Use recursive route discovery to find all route files in subdirectories
|
|
478
|
-
const discoveredRoutes = discoverRouteFiles(apiDir);
|
|
479
|
-
|
|
480
|
-
// Collect all API files: index.ts and discovered subdirectory routes
|
|
481
|
-
const apiFiles: string[] = [];
|
|
482
|
-
|
|
483
|
-
// Check for root index.ts
|
|
484
|
-
const indexFile = join(apiDir, 'index.ts');
|
|
485
|
-
if (existsSync(indexFile)) {
|
|
486
|
-
apiFiles.push(indexFile);
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
// Add all discovered route files
|
|
490
|
-
for (const route of discoveredRoutes) {
|
|
491
|
-
apiFiles.push(route.filepath);
|
|
492
|
-
|
|
493
|
-
// Generate auto-mount code for this subdirectory route
|
|
494
|
-
subRouteInserts.push(`await (async() => {
|
|
495
|
-
const { getRouter } = await import('@agentuity/runtime');
|
|
496
|
-
const router = getRouter()!;
|
|
497
|
-
const ${route.variableName} = (await import('${route.importPath}')).default;
|
|
498
|
-
router.route('${route.mountPath}', ${route.variableName});
|
|
499
|
-
})();`);
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
for (const apiFile of apiFiles) {
|
|
503
|
-
// Quick check: skip files that don't contain createRouter or Hono
|
|
504
|
-
// This avoids expensive AST parsing for utility files
|
|
505
|
-
const fileContent = await Bun.file(apiFile).text();
|
|
506
|
-
if (!fileContent.includes('createRouter') && !fileContent.includes('new Hono')) {
|
|
507
|
-
logger.trace(`Skipping ${apiFile}: no createRouter or Hono found`);
|
|
508
|
-
continue;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
try {
|
|
512
|
-
const routes = await parseRoute(rootDir, apiFile, projectId, deploymentId);
|
|
513
|
-
|
|
514
|
-
// Extract schemas from agents for routes that use validators
|
|
515
|
-
for (const route of routes) {
|
|
516
|
-
// Check if route has custom schema overrides from validator({ input, output })
|
|
517
|
-
const hasCustomInput = route.config?.inputSchemaVariable;
|
|
518
|
-
const hasCustomOutput = route.config?.outputSchemaVariable;
|
|
519
|
-
|
|
520
|
-
// If route uses agent.validator(), get schemas from the agent (unless overridden)
|
|
521
|
-
if (
|
|
522
|
-
route.config?.agentImportPath &&
|
|
523
|
-
(!hasCustomInput || !hasCustomOutput)
|
|
524
|
-
) {
|
|
525
|
-
const agentImportPath = route.config.agentImportPath as string;
|
|
526
|
-
// Match by import path: @agent/zod-test -> src/agent/zod-test/agent.ts
|
|
527
|
-
// Normalize import path by removing leading '@' -> agent/zod-test
|
|
528
|
-
const importPattern = agentImportPath.replace(/^@/, '');
|
|
529
|
-
// Escape regex special characters for safe pattern matching
|
|
530
|
-
const escapedPattern = importPattern.replace(
|
|
531
|
-
/[.*+?^${}()|[\]\\]/g,
|
|
532
|
-
'\\$&'
|
|
533
|
-
);
|
|
534
|
-
// Match as complete path segment to avoid false positives (e.g., "agent/hello" matching "agent/hello-world")
|
|
535
|
-
const segmentPattern = new RegExp(`(^|/)${escapedPattern}(/|$)`);
|
|
536
|
-
|
|
537
|
-
for (const [, agentMd] of agentMetadata) {
|
|
538
|
-
const agentFilename = agentMd.get('filename');
|
|
539
|
-
if (agentFilename && segmentPattern.test(agentFilename)) {
|
|
540
|
-
// Use agent schemas unless overridden
|
|
541
|
-
const inputSchemaCode = hasCustomInput
|
|
542
|
-
? undefined
|
|
543
|
-
: agentMd.get('inputSchemaCode');
|
|
544
|
-
const outputSchemaCode = hasCustomOutput
|
|
545
|
-
? undefined
|
|
546
|
-
: agentMd.get('outputSchemaCode');
|
|
547
|
-
|
|
548
|
-
if (inputSchemaCode || outputSchemaCode) {
|
|
549
|
-
route.schema = {
|
|
550
|
-
input: inputSchemaCode,
|
|
551
|
-
output: outputSchemaCode,
|
|
552
|
-
};
|
|
553
|
-
}
|
|
554
|
-
break;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
// TODO: Extract inline schema code from custom validator({ input: z.string(), output: ... })
|
|
560
|
-
// For now, custom schema overrides with inline code are not extracted (would require parsing the validator call's object expression)
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
apiRoutesMetadata.push(...routes);
|
|
564
|
-
|
|
565
|
-
// Collect route info for RouteRegistry generation
|
|
566
|
-
for (const route of routes) {
|
|
567
|
-
routeInfoList.push({
|
|
568
|
-
method: route.method.toUpperCase(),
|
|
569
|
-
path: route.path,
|
|
570
|
-
filename: route.filename,
|
|
571
|
-
hasValidator: route.config?.hasValidator === true,
|
|
572
|
-
routeType: route.type || 'api',
|
|
573
|
-
agentVariable: route.config?.agentVariable as string | undefined,
|
|
574
|
-
agentImportPath: route.config?.agentImportPath as string | undefined,
|
|
575
|
-
inputSchemaVariable: route.config?.inputSchemaVariable as
|
|
576
|
-
| string
|
|
577
|
-
| undefined,
|
|
578
|
-
outputSchemaVariable: route.config?.outputSchemaVariable as
|
|
579
|
-
| string
|
|
580
|
-
| undefined,
|
|
581
|
-
stream:
|
|
582
|
-
route.config?.stream !== undefined && route.config.stream !== null
|
|
583
|
-
? Boolean(route.config.stream)
|
|
584
|
-
: route.type === 'stream'
|
|
585
|
-
? true
|
|
586
|
-
: undefined,
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
} catch (error) {
|
|
590
|
-
// Skip files that don't have proper router setup despite containing createRouter/Hono
|
|
591
|
-
// (e.g., files that import but don't use them, or have syntax errors)
|
|
592
|
-
if (error instanceof Error) {
|
|
593
|
-
if (
|
|
594
|
-
error.message.includes('could not find default export') ||
|
|
595
|
-
error.message.includes('could not find an proper createRouter')
|
|
596
|
-
) {
|
|
597
|
-
logger.trace(`Skipping ${apiFile}: ${error.message}`);
|
|
598
|
-
} else {
|
|
599
|
-
throw error;
|
|
600
|
-
}
|
|
601
|
-
} else {
|
|
602
|
-
throw error;
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
// Generate RouteRegistry for type-safe route access
|
|
609
|
-
if (routeInfoList.length > 0) {
|
|
610
|
-
logger.trace(`Generating RouteRegistry with ${routeInfoList.length} routes`);
|
|
611
|
-
generateRouteRegistry(srcDir, routeInfoList);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
// Auto-mount src/api/index.ts if it exists
|
|
615
|
-
const apiIndexPath = join(srcDir, 'api', 'index.ts');
|
|
616
|
-
if (existsSync(apiIndexPath)) {
|
|
617
|
-
inserts.push(`await (async() => {
|
|
618
|
-
const { getRouter } = await import('@agentuity/runtime');
|
|
619
|
-
const router = getRouter()!;
|
|
620
|
-
const api = require('./src/api/index').default;
|
|
621
|
-
router.route('/api', api);
|
|
622
|
-
})();`);
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
// Auto-mount subdirectory routes (src/api/foo/route.ts -> /api/foo)
|
|
626
|
-
for (const subRouteInsert of subRouteInserts) {
|
|
627
|
-
inserts.push(subRouteInsert);
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
// Only create the workbench routes if workbench is actually configured
|
|
631
|
-
if (workbenchConfig) {
|
|
632
|
-
inserts.push(`await (async() => {
|
|
633
|
-
const { createWorkbenchRouter, getRouter } = await import('@agentuity/runtime');
|
|
634
|
-
const router = getRouter()!;
|
|
635
|
-
const workbenchRouter = createWorkbenchRouter();
|
|
636
|
-
router.route('/', workbenchRouter);
|
|
637
|
-
})();`);
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
// Add web routes AFTER API routes (catch-all must be last)
|
|
641
|
-
if (webRoutesInsert) {
|
|
642
|
-
inserts.push(webRoutesInsert);
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
const file = Bun.file(args.path);
|
|
646
|
-
let contents = await file.text();
|
|
647
|
-
// Use AST-based parsing to reliably find createApp statement end
|
|
648
|
-
const insertPos = findCreateAppEndPosition(contents);
|
|
649
|
-
|
|
650
|
-
// Add initialization call after all agent registrations
|
|
651
|
-
const setupCall = `
|
|
652
|
-
// Initialize providers and run agent setup callbacks after all agents are registered
|
|
653
|
-
await (async() => {
|
|
654
|
-
const { runAgentSetups, getThreadProvider, getSessionProvider, getAppState } = await import('@agentuity/runtime');
|
|
655
|
-
|
|
656
|
-
const threadProvider = getThreadProvider();
|
|
657
|
-
const sessionProvider = getSessionProvider();
|
|
658
|
-
|
|
659
|
-
const state = getAppState();
|
|
660
|
-
|
|
661
|
-
// Initialize providers first
|
|
662
|
-
await threadProvider.initialize(state);
|
|
663
|
-
await sessionProvider.initialize(state);
|
|
664
|
-
|
|
665
|
-
// Then run agent setups
|
|
666
|
-
await runAgentSetups(state);
|
|
667
|
-
})();`;
|
|
668
|
-
|
|
669
|
-
if (insertPos > 0) {
|
|
670
|
-
contents =
|
|
671
|
-
contents.slice(0, insertPos) +
|
|
672
|
-
'\n\n' +
|
|
673
|
-
inserts.join('\n') +
|
|
674
|
-
setupCall +
|
|
675
|
-
contents.slice(insertPos);
|
|
676
|
-
} else {
|
|
677
|
-
// Fallback: append to end if AST parsing fails
|
|
678
|
-
logger.warn('Could not find createApp in AST, appending code to end of file');
|
|
679
|
-
contents += `\n${inserts.join('\n')}${setupCall}`;
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
// generate the build metadata
|
|
683
|
-
metadata = {
|
|
684
|
-
routes: apiRoutesMetadata,
|
|
685
|
-
agents: [],
|
|
686
|
-
};
|
|
687
|
-
|
|
688
|
-
// Validate required metadata properties and build agent metadata
|
|
689
|
-
for (const [, v] of agentMetadata) {
|
|
690
|
-
if (!v.has('filename')) {
|
|
691
|
-
throw new MetadataPropertyMissingError({
|
|
692
|
-
name: 'filename',
|
|
693
|
-
message: 'agent metadata is missing expected filename property',
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
|
-
if (!v.has('id')) {
|
|
697
|
-
throw new MetadataPropertyMissingError({
|
|
698
|
-
name: 'id',
|
|
699
|
-
message: 'agent metadata is missing expected id property',
|
|
700
|
-
});
|
|
701
|
-
}
|
|
702
|
-
if (!v.has('version')) {
|
|
703
|
-
throw new MetadataPropertyMissingError({
|
|
704
|
-
name: 'version',
|
|
705
|
-
message: 'agent metadata is missing expected version property',
|
|
706
|
-
});
|
|
707
|
-
}
|
|
708
|
-
if (!v.has('name')) {
|
|
709
|
-
throw new MetadataPropertyMissingError({
|
|
710
|
-
name: 'name',
|
|
711
|
-
message: 'agent metadata is missing expected name property',
|
|
712
|
-
});
|
|
713
|
-
}
|
|
714
|
-
if (!v.has('agentId')) {
|
|
715
|
-
throw new MetadataPropertyMissingError({
|
|
716
|
-
name: 'agentId',
|
|
717
|
-
message: 'agent metadata is missing expected agentId property',
|
|
718
|
-
});
|
|
719
|
-
}
|
|
720
|
-
const agentData: BuildMetadata['agents'][number] = {
|
|
721
|
-
filename: v.get('filename')!,
|
|
722
|
-
id: v.get('id')!,
|
|
723
|
-
agentId: v.get('agentId')!,
|
|
724
|
-
version: v.get('version')!,
|
|
725
|
-
name: v.get('name')!,
|
|
726
|
-
description: v.get('description') ?? '',
|
|
727
|
-
projectId,
|
|
728
|
-
};
|
|
729
|
-
|
|
730
|
-
// Extract schema codes if available
|
|
731
|
-
const inputSchemaCode = v.get('inputSchemaCode');
|
|
732
|
-
const outputSchemaCode = v.get('outputSchemaCode');
|
|
733
|
-
if (inputSchemaCode || outputSchemaCode) {
|
|
734
|
-
agentData.schema = {
|
|
735
|
-
input: inputSchemaCode,
|
|
736
|
-
output: outputSchemaCode,
|
|
737
|
-
};
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
const evalsStr = v.get('evals');
|
|
741
|
-
if (evalsStr) {
|
|
742
|
-
logger.trace(
|
|
743
|
-
`[plugin] Found evals string for agent ${agentData.name}, parsing...`
|
|
744
|
-
);
|
|
745
|
-
try {
|
|
746
|
-
const parsedEvals = JSON.parse(evalsStr) as Array<
|
|
747
|
-
Omit<
|
|
748
|
-
NonNullable<BuildMetadata['agents'][number]['evals']>[number],
|
|
749
|
-
'agentIdentifier' | 'projectId'
|
|
750
|
-
>
|
|
751
|
-
>;
|
|
752
|
-
agentData.evals = parsedEvals.map((evalItem) => ({
|
|
753
|
-
...evalItem,
|
|
754
|
-
agentIdentifier: agentData.agentId,
|
|
755
|
-
projectId,
|
|
756
|
-
}));
|
|
757
|
-
logger.trace(
|
|
758
|
-
`[plugin] Successfully parsed ${agentData.evals?.length ?? 0} eval(s) for agent ${agentData.name}`
|
|
759
|
-
);
|
|
760
|
-
} catch (e) {
|
|
761
|
-
logger.trace(
|
|
762
|
-
`[plugin] Failed to parse evals for agent ${agentData.name}: ${e}`
|
|
763
|
-
);
|
|
764
|
-
console.warn(`Failed to parse evals for agent ${agentData.name}: ${e}`);
|
|
765
|
-
}
|
|
766
|
-
} else {
|
|
767
|
-
logger.trace(`[plugin] No evals found for agent ${agentData.name}`);
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
metadata.agents!.push(agentData);
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
return {
|
|
774
|
-
contents,
|
|
775
|
-
loader: 'ts',
|
|
776
|
-
};
|
|
777
|
-
}
|
|
778
|
-
);
|
|
779
|
-
},
|
|
780
|
-
};
|
|
781
|
-
|
|
782
|
-
export default AgentuityBundler;
|