forgeos 0.1.0-alpha.2 → 0.1.0-alpha.3
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 +38 -3
- package/README.md +6 -5
- package/package.json +5 -4
- package/src/forge/_generated/actionSubscriptions.json +2 -2
- package/src/forge/_generated/actionSubscriptions.ts +3 -3
- package/src/forge/_generated/agentAdapterManifest.json +2 -2
- package/src/forge/_generated/agentAdapterManifest.ts +3 -3
- package/src/forge/_generated/agentContract.json +2 -2
- package/src/forge/_generated/agentContract.ts +183 -50
- package/src/forge/_generated/agentQuickstart.md +3 -1
- package/src/forge/_generated/agentTools.json +2 -0
- package/src/forge/_generated/agentTools.md +16 -0
- package/src/forge/_generated/agentTools.ts +12 -0
- package/src/forge/_generated/aiContext.ts +67 -1
- package/src/forge/_generated/aiModels.json +2 -2
- package/src/forge/_generated/aiModels.ts +17 -1
- package/src/forge/_generated/aiProviders.json +1 -1
- package/src/forge/_generated/aiProviders.ts +1 -1
- package/src/forge/_generated/aiRegistry.json +2 -2
- package/src/forge/_generated/aiRegistry.ts +7 -5
- package/src/forge/_generated/api.json +2 -2
- package/src/forge/_generated/api.ts +1 -1
- package/src/forge/_generated/appGraph.json +2 -2
- package/src/forge/_generated/appGraph.ts +288 -180
- package/src/forge/_generated/appMap.md +21 -1
- package/src/forge/_generated/artifactManifest.json +2 -2
- package/src/forge/_generated/artifactManifest.ts +2 -2
- package/src/forge/_generated/authClaims.json +1 -1
- package/src/forge/_generated/authClaims.ts +1 -1
- package/src/forge/_generated/authConfig.json +1 -1
- package/src/forge/_generated/authConfig.ts +1 -1
- package/src/forge/_generated/authContext.ts +1 -1
- package/src/forge/_generated/authRegistry.json +1 -1
- package/src/forge/_generated/authRegistry.ts +1 -1
- package/src/forge/_generated/buildInfo.json +2 -2
- package/src/forge/_generated/buildInfo.ts +4 -4
- package/src/forge/_generated/capabilityMap.json +2 -2
- package/src/forge/_generated/capabilityMap.md +1 -1
- package/src/forge/_generated/capabilityMap.ts +2 -2
- package/src/forge/_generated/client.ts +1 -1
- package/src/forge/_generated/clientApi.ts +1 -1
- package/src/forge/_generated/clientManifest.json +2 -2
- package/src/forge/_generated/clientManifest.ts +3 -3
- package/src/forge/_generated/clientTypes.ts +1 -1
- package/src/forge/_generated/configRegistry.json +1 -1
- package/src/forge/_generated/configRegistry.ts +1 -1
- package/src/forge/_generated/dataGraph.json +2 -2
- package/src/forge/_generated/dataGraph.ts +3 -3
- package/src/forge/_generated/db.json +1 -1
- package/src/forge/_generated/db.ts +1 -1
- package/src/forge/_generated/dbSecurityManifest.json +1 -1
- package/src/forge/_generated/dbSecurityManifest.ts +1 -1
- package/src/forge/_generated/dbSessionContext.json +1 -1
- package/src/forge/_generated/dbSessionContext.ts +1 -1
- package/src/forge/_generated/deployManifest.json +2 -2
- package/src/forge/_generated/deployManifest.ts +7 -7
- package/src/forge/_generated/devManifest.json +2 -2
- package/src/forge/_generated/devManifest.ts +18 -3
- package/src/forge/_generated/envSchema.json +1 -1
- package/src/forge/_generated/envSchema.ts +1 -1
- package/src/forge/_generated/frontendGraph.json +1 -1
- package/src/forge/_generated/frontendGraph.ts +1 -1
- package/src/forge/_generated/importGuards.json +1 -1
- package/src/forge/_generated/importGuards.ts +1 -1
- package/src/forge/_generated/index.ts +2 -1
- package/src/forge/_generated/liveProductionManifest.json +1 -1
- package/src/forge/_generated/liveProductionManifest.ts +1 -1
- package/src/forge/_generated/liveProtocol.json +1 -1
- package/src/forge/_generated/liveProtocol.ts +1 -1
- package/src/forge/_generated/liveQueryRegistry.json +2 -2
- package/src/forge/_generated/liveQueryRegistry.ts +3 -3
- package/src/forge/_generated/liveTransportConfig.json +1 -1
- package/src/forge/_generated/liveTransportConfig.ts +1 -1
- package/src/forge/_generated/makeRegistry.json +2 -2
- package/src/forge/_generated/makeRegistry.ts +16 -2
- package/src/forge/_generated/makeTemplates.json +2 -2
- package/src/forge/_generated/makeTemplates.ts +6 -1
- package/src/forge/_generated/mockMap.json +1 -1
- package/src/forge/_generated/mockMap.ts +1 -1
- package/src/forge/_generated/operationPlaybooks.md +34 -14
- package/src/forge/_generated/packageGraph.json +2 -2
- package/src/forge/_generated/packageGraph.ts +8808 -4723
- package/src/forge/_generated/packageUpgradeRegistry.json +2 -2
- package/src/forge/_generated/packageUpgradeRegistry.ts +2 -2
- package/src/forge/_generated/permissionMatrix.json +2 -2
- package/src/forge/_generated/permissionMatrix.ts +3 -3
- package/src/forge/_generated/policyRegistry.json +2 -2
- package/src/forge/_generated/policyRegistry.ts +3 -3
- package/src/forge/_generated/queryRegistry.json +2 -2
- package/src/forge/_generated/queryRegistry.ts +3 -3
- package/src/forge/_generated/react.d.ts +1 -1
- package/src/forge/_generated/react.ts +1 -1
- package/src/forge/_generated/reactManifest.json +2 -2
- package/src/forge/_generated/reactManifest.ts +3 -3
- package/src/forge/_generated/releaseManifest.json +2 -2
- package/src/forge/_generated/releaseManifest.ts +3 -3
- package/src/forge/_generated/rlsPolicies.json +1 -1
- package/src/forge/_generated/rlsPolicies.sql +1 -1
- package/src/forge/_generated/rlsPolicies.ts +1 -1
- package/src/forge/_generated/runtimeGraph.json +2 -2
- package/src/forge/_generated/runtimeGraph.ts +3 -3
- package/src/forge/_generated/runtimeMatrix.json +2 -2
- package/src/forge/_generated/runtimeMatrix.ts +8684 -1939
- package/src/forge/_generated/runtimeRegistry.ts +1 -1
- package/src/forge/_generated/runtimeRules.md +13 -1
- package/src/forge/_generated/secretRegistry.json +1 -1
- package/src/forge/_generated/secretRegistry.ts +1 -1
- package/src/forge/_generated/secretsContext.ts +1 -1
- package/src/forge/_generated/serverApi.ts +1 -1
- package/src/forge/_generated/sourceMapManifest.json +2 -2
- package/src/forge/_generated/sourceMapManifest.ts +2 -2
- package/src/forge/_generated/sqlPlan.json +1 -1
- package/src/forge/_generated/sqlPlan.ts +1 -1
- package/src/forge/_generated/subscriptionManifest.json +2 -2
- package/src/forge/_generated/subscriptionManifest.ts +3 -3
- package/src/forge/_generated/symbolicationManifest.json +2 -2
- package/src/forge/_generated/symbolicationManifest.ts +2 -2
- package/src/forge/_generated/telemetryRegistry.json +2 -2
- package/src/forge/_generated/telemetryRegistry.ts +3 -3
- package/src/forge/_generated/telemetrySinks.json +2 -2
- package/src/forge/_generated/telemetrySinks.ts +2 -2
- package/src/forge/_generated/tenantScope.json +2 -2
- package/src/forge/_generated/tenantScope.ts +3 -3
- package/src/forge/_generated/testGraph.json +2 -2
- package/src/forge/_generated/testGraph.ts +17 -7
- package/src/forge/_generated/testPlanRegistry.json +2 -2
- package/src/forge/_generated/testPlanRegistry.ts +2 -2
- package/src/forge/_generated/uiRoutes.json +1 -1
- package/src/forge/_generated/uiRoutes.ts +1 -1
- package/src/forge/_generated/uiScenarios.json +1 -1
- package/src/forge/_generated/uiScenarios.ts +1 -1
- package/src/forge/_generated/uiTestManifest.json +2 -2
- package/src/forge/_generated/uiTestManifest.ts +2 -2
- package/src/forge/_generated/workflowRegistry.json +2 -2
- package/src/forge/_generated/workflowRegistry.ts +3 -3
- package/src/forge/_generated/workflowSubscriptions.json +2 -2
- package/src/forge/_generated/workflowSubscriptions.ts +3 -3
- package/src/forge/cli/ai.ts +186 -1
- package/src/forge/cli/commands.ts +5 -0
- package/src/forge/cli/parse.ts +30 -3
- package/src/forge/compiler/agent-contract/build.ts +281 -8
- package/src/forge/compiler/agent-contract/types.ts +41 -0
- package/src/forge/compiler/ai-registry/build.ts +62 -1
- package/src/forge/compiler/ai-registry/constants.ts +1 -1
- package/src/forge/compiler/ai-registry/parse.ts +98 -4
- package/src/forge/compiler/app-graph/forge-apis.ts +1 -0
- package/src/forge/compiler/dev-manifest/build.ts +3 -0
- package/src/forge/compiler/make-registry/build.ts +13 -0
- package/src/forge/compiler/orchestrator/plan.ts +11 -0
- package/src/forge/compiler/orchestrator/serialize.ts +68 -0
- package/src/forge/compiler/types/ai-registry.ts +25 -1
- package/src/forge/compiler/types/app-graph.ts +1 -0
- package/src/forge/compiler/types/cli.ts +1 -0
- package/src/forge/compiler/types/dev-manifest.ts +3 -0
- package/src/forge/dev/server.ts +508 -1
- package/src/forge/make/index.ts +126 -3
- package/src/forge/make/templates.ts +188 -0
- package/src/forge/make/types.ts +1 -0
- package/src/forge/runtime/ai/context.ts +210 -5
- package/src/forge/runtime/ai/types.ts +70 -0
- package/src/forge/runtime/context/create-context.ts +30 -6
- package/src/forge/server.ts +82 -0
- package/src/forge/version.ts +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ForgeAiProvider } from "../types/ai-registry.ts";
|
|
2
2
|
|
|
3
3
|
const AI_METHOD_PATTERN =
|
|
4
|
-
/(?:ctx\.ai|ai)\.(generateText|streamText|generateStructured)\s*\(/g;
|
|
4
|
+
/(?:(?:ctx\.ai|ai)\.(generateText|streamText|generateStructured|runAgent)|ctx\.agent\.(run))\s*\(/g;
|
|
5
5
|
|
|
6
6
|
const PROVIDER_PATTERN =
|
|
7
7
|
/provider\s*:\s*["'](openai|anthropic|gateway)["']/;
|
|
@@ -11,7 +11,7 @@ const MODEL_PATTERN = /model\s*:\s*["']([^"']+)["']/;
|
|
|
11
11
|
const PURPOSE_PATTERN = /purpose\s*:\s*["']([^"']+)["']/;
|
|
12
12
|
|
|
13
13
|
export interface ParsedAiCall {
|
|
14
|
-
method: "generateText" | "streamText" | "generateStructured";
|
|
14
|
+
method: "generateText" | "streamText" | "generateStructured" | "runAgent";
|
|
15
15
|
provider?: ForgeAiProvider;
|
|
16
16
|
model?: string;
|
|
17
17
|
purpose?: string;
|
|
@@ -21,7 +21,7 @@ export function parseAiCallsFromSlice(sourceSlice: string): ParsedAiCall[] {
|
|
|
21
21
|
const calls: ParsedAiCall[] = [];
|
|
22
22
|
|
|
23
23
|
for (const match of sourceSlice.matchAll(AI_METHOD_PATTERN)) {
|
|
24
|
-
const method = match[1] as ParsedAiCall["method"];
|
|
24
|
+
const method = (match[1] ?? (match[2] ? "runAgent" : "")) as ParsedAiCall["method"];
|
|
25
25
|
const start = match.index ?? 0;
|
|
26
26
|
const window = sourceSlice.slice(start, start + 600);
|
|
27
27
|
|
|
@@ -49,8 +49,102 @@ export function parseAiCallsFromSlice(sourceSlice: string): ParsedAiCall[] {
|
|
|
49
49
|
return calls;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
const FORBIDDEN_AI_CONTEXT_PATTERN = /ctx\.ai
|
|
52
|
+
const FORBIDDEN_AI_CONTEXT_PATTERN = /ctx\.(?:ai\.|agent\.run\s*\()/;
|
|
53
53
|
|
|
54
54
|
export function detectCtxAiUsage(sourceSlice: string): boolean {
|
|
55
55
|
return FORBIDDEN_AI_CONTEXT_PATTERN.test(sourceSlice);
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
const DESCRIPTION_PATTERN = /description\s*:\s*["'`]([^"'`]+)["'`]/;
|
|
59
|
+
const RISK_PATTERN = /risk\s*:\s*["'](read|write|external|destructive)["']/;
|
|
60
|
+
const STRICT_PATTERN = /strict\s*:\s*(true|false)/;
|
|
61
|
+
const NEEDS_APPROVAL_PATTERN = /needsApproval\s*:\s*(true|false|async\s*\(|\([^)]*\)\s*=>|[A-Za-z_$][A-Za-z0-9_$]*)/;
|
|
62
|
+
const INSTRUCTIONS_PATTERN = /instructions\s*:\s*["'`]([^"'`]+)["'`]/;
|
|
63
|
+
const TOOL_ARRAY_PATTERN = /tools\s*:\s*\[([^\]]*)\]/s;
|
|
64
|
+
const TOOL_OBJECT_PATTERN = /tools\s*:\s*\{([^}]*)\}/s;
|
|
65
|
+
const STOP_TOOL_PATTERN = /stopWhen\s*:\s*\{[^}]*kind\s*:\s*["']toolCall["'][^}]*toolName\s*:\s*["']([^"']+)["'][^}]*\}/s;
|
|
66
|
+
const STOP_STEP_PATTERN = /stopWhen\s*:\s*\{[^}]*kind\s*:\s*["']stepCount["'][^}]*maxSteps\s*:\s*(\d+)[^}]*\}/s;
|
|
67
|
+
const MAX_STEPS_PATTERN = /maxSteps\s*:\s*(\d+)/;
|
|
68
|
+
|
|
69
|
+
export interface ParsedAiToolMeta {
|
|
70
|
+
description?: string;
|
|
71
|
+
risk: "read" | "write" | "external" | "destructive" | "unknown";
|
|
72
|
+
strict: boolean;
|
|
73
|
+
needsApproval: boolean | "dynamic";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface ParsedAiAgentMeta {
|
|
77
|
+
provider?: ForgeAiProvider;
|
|
78
|
+
model?: string;
|
|
79
|
+
instructions?: string;
|
|
80
|
+
tools: string[];
|
|
81
|
+
stopWhen:
|
|
82
|
+
| { kind: "stepCount"; maxSteps: number }
|
|
83
|
+
| { kind: "toolCall"; toolName: string }
|
|
84
|
+
| { kind: "default" };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function parseBooleanOrDynamic(value: string | undefined): boolean | "dynamic" {
|
|
88
|
+
if (value === "true") return true;
|
|
89
|
+
if (value === "false") return false;
|
|
90
|
+
return "dynamic";
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function parseStringList(raw: string | undefined): string[] {
|
|
94
|
+
if (!raw) return [];
|
|
95
|
+
return [...raw.matchAll(/["'`]([^"'`]+)["'`]/g)]
|
|
96
|
+
.map((match) => match[1] ?? "")
|
|
97
|
+
.filter(Boolean)
|
|
98
|
+
.sort();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function parseObjectToolKeys(raw: string | undefined): string[] {
|
|
102
|
+
if (!raw) return [];
|
|
103
|
+
const explicit = [...raw.matchAll(/([A-Za-z_$][A-Za-z0-9_$]*)\s*:/g)]
|
|
104
|
+
.map((match) => match[1] ?? "")
|
|
105
|
+
.filter(Boolean);
|
|
106
|
+
const shorthand = raw
|
|
107
|
+
.split(",")
|
|
108
|
+
.map((part) => part.trim())
|
|
109
|
+
.filter((part) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(part));
|
|
110
|
+
return [...new Set([...explicit, ...shorthand])].sort();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function parseAiToolMeta(sourceSlice: string): ParsedAiToolMeta {
|
|
114
|
+
const description = DESCRIPTION_PATTERN.exec(sourceSlice)?.[1];
|
|
115
|
+
const risk = RISK_PATTERN.exec(sourceSlice)?.[1] as ParsedAiToolMeta["risk"] | undefined;
|
|
116
|
+
const strict = STRICT_PATTERN.exec(sourceSlice)?.[1] === "true";
|
|
117
|
+
const needsApprovalMatch = NEEDS_APPROVAL_PATTERN.exec(sourceSlice)?.[1];
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
...(description ? { description } : {}),
|
|
121
|
+
risk: risk ?? "unknown",
|
|
122
|
+
strict,
|
|
123
|
+
needsApproval: needsApprovalMatch
|
|
124
|
+
? parseBooleanOrDynamic(needsApprovalMatch)
|
|
125
|
+
: false,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function parseAiAgentMeta(sourceSlice: string): ParsedAiAgentMeta {
|
|
130
|
+
const provider = PROVIDER_PATTERN.exec(sourceSlice)?.[1] as ForgeAiProvider | undefined;
|
|
131
|
+
const model = MODEL_PATTERN.exec(sourceSlice)?.[1];
|
|
132
|
+
const instructions = INSTRUCTIONS_PATTERN.exec(sourceSlice)?.[1];
|
|
133
|
+
const arrayTools = parseStringList(TOOL_ARRAY_PATTERN.exec(sourceSlice)?.[1]);
|
|
134
|
+
const objectTools = parseObjectToolKeys(TOOL_OBJECT_PATTERN.exec(sourceSlice)?.[1]);
|
|
135
|
+
const stopTool = STOP_TOOL_PATTERN.exec(sourceSlice)?.[1];
|
|
136
|
+
const stopStepsRaw =
|
|
137
|
+
STOP_STEP_PATTERN.exec(sourceSlice)?.[1] ?? MAX_STEPS_PATTERN.exec(sourceSlice)?.[1];
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
...(provider ? { provider } : {}),
|
|
141
|
+
...(model ? { model } : {}),
|
|
142
|
+
...(instructions ? { instructions } : {}),
|
|
143
|
+
tools: [...new Set([...arrayTools, ...objectTools])].sort(),
|
|
144
|
+
stopWhen: stopTool
|
|
145
|
+
? { kind: "toolCall", toolName: stopTool }
|
|
146
|
+
: stopStepsRaw
|
|
147
|
+
? { kind: "stepCount", maxSteps: Number(stopStepsRaw) }
|
|
148
|
+
: { kind: "default" },
|
|
149
|
+
};
|
|
150
|
+
}
|
|
@@ -61,6 +61,9 @@ function buildRoutes(
|
|
|
61
61
|
{ method: "GET", path: "/health", purpose: "health" },
|
|
62
62
|
{ method: "GET", path: "/entries", purpose: "entries" },
|
|
63
63
|
{ method: "GET", path: "/queries", purpose: "queries" },
|
|
64
|
+
{ method: "POST", path: "/ai/agents/chat", purpose: "ai-agent-chat" },
|
|
65
|
+
{ method: "POST", path: "/ai/agents/run", purpose: "ai-agent-run" },
|
|
66
|
+
{ method: "GET", path: "/ai/providers", purpose: "ai-providers" },
|
|
64
67
|
{ method: "GET", path: "/workflows", purpose: "workflows" },
|
|
65
68
|
{ method: "GET", path: "/workflows/runs", purpose: "workflow-runs" },
|
|
66
69
|
{ method: "POST", path: "/workflows/process", purpose: "workflow-process" },
|
|
@@ -34,6 +34,7 @@ export function buildMakeRegistry(generatorVersion: string): MakeRegistryArtifac
|
|
|
34
34
|
"forge make list --json",
|
|
35
35
|
"forge make explain <primitive> --json",
|
|
36
36
|
"forge make ui --framework vite --dry-run --json",
|
|
37
|
+
"forge make ai-chat support --dry-run --json",
|
|
37
38
|
"forge make resource <name> --fields title:text,status:enum(open,closed) --dry-run --json",
|
|
38
39
|
"forge make resource <name> --fields title:text --with-ui --yes",
|
|
39
40
|
"forge make apply <planId>",
|
|
@@ -123,6 +124,17 @@ export function buildMakeRegistry(generatorVersion: string): MakeRegistryArtifac
|
|
|
123
124
|
modifies: [],
|
|
124
125
|
examples: ["forge make ui --framework vite --yes"],
|
|
125
126
|
},
|
|
127
|
+
{
|
|
128
|
+
name: "ai-chat",
|
|
129
|
+
summary: "Add a Forge AI agent and React chat component backed by /ai/agents/run.",
|
|
130
|
+
creates: [
|
|
131
|
+
"src/ai/<name>Agent.ts",
|
|
132
|
+
"web/components/<Name>AiChat.tsx",
|
|
133
|
+
"web/app/<name>-ai/page.tsx when web/app exists",
|
|
134
|
+
],
|
|
135
|
+
modifies: [],
|
|
136
|
+
examples: ["forge make ai-chat support --yes"],
|
|
137
|
+
},
|
|
126
138
|
{
|
|
127
139
|
name: "resource",
|
|
128
140
|
summary: "Add schema, policies, CRUD, queries, liveQuery, optional UI, and tests.",
|
|
@@ -155,6 +167,7 @@ export function buildMakeTemplates(): MakeTemplateArtifact {
|
|
|
155
167
|
{ name: "component", sourceKind: "frontend", outputPattern: "web/components/<name>.tsx" },
|
|
156
168
|
{ name: "page", sourceKind: "frontend", outputPattern: "web/app/<route>/page.tsx" },
|
|
157
169
|
{ name: "ui", sourceKind: "frontend", outputPattern: "web/src/App.tsx" },
|
|
170
|
+
{ name: "ai-chat", sourceKind: "frontend", outputPattern: "web/components/<name>AiChat.tsx" },
|
|
158
171
|
{ name: "placeholder-test", sourceKind: "test", outputPattern: "tests/make-generated/<name>.test.ts" },
|
|
159
172
|
],
|
|
160
173
|
};
|
|
@@ -54,6 +54,8 @@ import { buildDevManifest } from "../dev-manifest/build.ts";
|
|
|
54
54
|
import { buildRuntimeGraph } from "../runtime-graph/build.ts";
|
|
55
55
|
import {
|
|
56
56
|
buildAgentContractArtifacts,
|
|
57
|
+
serializeAgentToolRegistryJson,
|
|
58
|
+
serializeAgentToolRegistryTs,
|
|
57
59
|
serializeCapabilityMapJson,
|
|
58
60
|
serializeCapabilityMapTs,
|
|
59
61
|
serializeAgentContractJson,
|
|
@@ -399,6 +401,15 @@ export function plan(input: PlanInput): EmitPlan {
|
|
|
399
401
|
serializeAgentContractJson(agentArtifacts.contract),
|
|
400
402
|
),
|
|
401
403
|
makeEmitFile(`${GENERATED_DIR}/appMap.md`, agentArtifacts.appMapMd),
|
|
404
|
+
makeEmitFile(
|
|
405
|
+
`${GENERATED_DIR}/agentTools.ts`,
|
|
406
|
+
serializeAgentToolRegistryTs(agentArtifacts.toolRegistry),
|
|
407
|
+
),
|
|
408
|
+
makeEmitFile(
|
|
409
|
+
`${GENERATED_DIR}/agentTools.json`,
|
|
410
|
+
serializeAgentToolRegistryJson(agentArtifacts.toolRegistry),
|
|
411
|
+
),
|
|
412
|
+
makeEmitFile(`${GENERATED_DIR}/agentTools.md`, agentArtifacts.agentToolsMd),
|
|
402
413
|
makeEmitFile(
|
|
403
414
|
`${GENERATED_DIR}/capabilityMap.ts`,
|
|
404
415
|
serializeCapabilityMapTs(agentArtifacts.capabilityMap),
|
|
@@ -680,6 +680,8 @@ export function serializeAiRegistryJson(registry: import("../types/ai-registry.t
|
|
|
680
680
|
inputHash: registry.inputHash,
|
|
681
681
|
providers: registry.providers,
|
|
682
682
|
generations: registry.generations,
|
|
683
|
+
tools: registry.tools,
|
|
684
|
+
agents: registry.agents,
|
|
683
685
|
diagnostics: registry.diagnostics,
|
|
684
686
|
};
|
|
685
687
|
return serializeCanonical(payload);
|
|
@@ -762,10 +764,76 @@ export interface ForgeGenerateStructuredInput<T> {
|
|
|
762
764
|
schema: ForgeFlexibleSchema<T>;
|
|
763
765
|
}
|
|
764
766
|
|
|
767
|
+
export type ForgeAiToolRisk = "read" | "write" | "external" | "destructive";
|
|
768
|
+
|
|
769
|
+
export interface ForgeAiToolRuntimeContext {
|
|
770
|
+
secrets: {
|
|
771
|
+
get(name: string): string;
|
|
772
|
+
optional(name: string): string | undefined;
|
|
773
|
+
has(name: string): boolean;
|
|
774
|
+
};
|
|
775
|
+
env: Record<string, string | undefined>;
|
|
776
|
+
telemetry?: {
|
|
777
|
+
traceId?: string;
|
|
778
|
+
capture(name: string, properties?: Record<string, unknown>): Promise<void>;
|
|
779
|
+
};
|
|
780
|
+
auth?: unknown;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
export interface ForgeAiToolDefinition<TArgs = unknown, TResult = unknown> {
|
|
784
|
+
description: string;
|
|
785
|
+
inputSchema: unknown;
|
|
786
|
+
outputSchema?: unknown;
|
|
787
|
+
strict?: boolean;
|
|
788
|
+
needsApproval?: boolean | ((args: TArgs) => boolean | Promise<boolean>);
|
|
789
|
+
risk?: ForgeAiToolRisk;
|
|
790
|
+
handler: (
|
|
791
|
+
ctx: ForgeAiToolRuntimeContext,
|
|
792
|
+
args: TArgs,
|
|
793
|
+
) => TResult | Promise<TResult>;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
export type ForgeAgentStopWhen =
|
|
797
|
+
| { kind: "stepCount"; maxSteps: number }
|
|
798
|
+
| { kind: "toolCall"; toolName: string };
|
|
799
|
+
|
|
800
|
+
export interface ForgeRunAgentInput {
|
|
801
|
+
provider?: ForgeAiProvider;
|
|
802
|
+
model: string;
|
|
803
|
+
prompt: string;
|
|
804
|
+
instructions: string;
|
|
805
|
+
purpose?: string;
|
|
806
|
+
tools?: Record<string, ForgeAiToolDefinition>;
|
|
807
|
+
stopWhen?: ForgeAgentStopWhen;
|
|
808
|
+
maxSteps?: number;
|
|
809
|
+
temperature?: number;
|
|
810
|
+
maxTokens?: number;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
export interface ForgeRunAgentResult {
|
|
814
|
+
text: string;
|
|
815
|
+
provider: ForgeAiProvider;
|
|
816
|
+
model: string;
|
|
817
|
+
purpose?: string;
|
|
818
|
+
usage: ForgeAiUsage;
|
|
819
|
+
latencyMs: number;
|
|
820
|
+
toolCalls: Array<{
|
|
821
|
+
toolName: string;
|
|
822
|
+
input: unknown;
|
|
823
|
+
}>;
|
|
824
|
+
toolResults: Array<{
|
|
825
|
+
toolName: string;
|
|
826
|
+
output: unknown;
|
|
827
|
+
}>;
|
|
828
|
+
steps: number;
|
|
829
|
+
estimatedCostUsd?: number;
|
|
830
|
+
}
|
|
831
|
+
|
|
765
832
|
export interface AiContext {
|
|
766
833
|
generateText(input: ForgeGenerateTextInput): Promise<ForgeGenerateTextResult>;
|
|
767
834
|
streamText(input: ForgeStreamTextInput): Promise<ForgeStreamTextResult>;
|
|
768
835
|
generateStructured<T>(input: ForgeGenerateStructuredInput<T>): Promise<T>;
|
|
836
|
+
runAgent(input: ForgeRunAgentInput): Promise<ForgeRunAgentResult>;
|
|
769
837
|
}
|
|
770
838
|
`;
|
|
771
839
|
}
|
|
@@ -18,10 +18,32 @@ export interface AiGenerationCall {
|
|
|
18
18
|
provider: ForgeAiProvider;
|
|
19
19
|
model: string;
|
|
20
20
|
purpose?: string;
|
|
21
|
-
method: "generateText" | "streamText" | "generateStructured";
|
|
21
|
+
method: "generateText" | "streamText" | "generateStructured" | "runAgent";
|
|
22
22
|
file: string;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
export interface AiToolDefinition {
|
|
26
|
+
name: string;
|
|
27
|
+
file: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
risk: "read" | "write" | "external" | "destructive" | "unknown";
|
|
30
|
+
strict: boolean;
|
|
31
|
+
needsApproval: boolean | "dynamic";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface AiAgentDefinition {
|
|
35
|
+
name: string;
|
|
36
|
+
file: string;
|
|
37
|
+
provider: ForgeAiProvider;
|
|
38
|
+
model: string;
|
|
39
|
+
instructions?: string;
|
|
40
|
+
tools: string[];
|
|
41
|
+
stopWhen:
|
|
42
|
+
| { kind: "stepCount"; maxSteps: number }
|
|
43
|
+
| { kind: "toolCall"; toolName: string }
|
|
44
|
+
| { kind: "default" };
|
|
45
|
+
}
|
|
46
|
+
|
|
25
47
|
export interface AiRegistry {
|
|
26
48
|
schemaVersion: string;
|
|
27
49
|
generatorVersion: string;
|
|
@@ -29,5 +51,7 @@ export interface AiRegistry {
|
|
|
29
51
|
inputHash: string;
|
|
30
52
|
providers: AiProviderDefinition[];
|
|
31
53
|
generations: AiGenerationCall[];
|
|
54
|
+
tools: AiToolDefinition[];
|
|
55
|
+
agents: AiAgentDefinition[];
|
|
32
56
|
diagnostics: unknown[];
|
|
33
57
|
}
|