@lakitu/sdk 0.1.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 +166 -0
- package/convex/_generated/api.d.ts +45 -0
- package/convex/_generated/api.js +23 -0
- package/convex/_generated/dataModel.d.ts +58 -0
- package/convex/_generated/server.d.ts +143 -0
- package/convex/_generated/server.js +93 -0
- package/convex/cloud/CLAUDE.md +238 -0
- package/convex/cloud/_generated/api.ts +84 -0
- package/convex/cloud/_generated/component.ts +861 -0
- package/convex/cloud/_generated/dataModel.ts +60 -0
- package/convex/cloud/_generated/server.ts +156 -0
- package/convex/cloud/convex.config.ts +16 -0
- package/convex/cloud/index.ts +29 -0
- package/convex/cloud/intentSchema/generate.ts +447 -0
- package/convex/cloud/intentSchema/index.ts +16 -0
- package/convex/cloud/intentSchema/types.ts +418 -0
- package/convex/cloud/ksaPolicy.ts +554 -0
- package/convex/cloud/mail.ts +92 -0
- package/convex/cloud/schema.ts +322 -0
- package/convex/cloud/utils/kanbanContext.ts +229 -0
- package/convex/cloud/workflows/agentBoard.ts +451 -0
- package/convex/cloud/workflows/agentPrompt.ts +272 -0
- package/convex/cloud/workflows/agentThread.ts +374 -0
- package/convex/cloud/workflows/compileSandbox.ts +146 -0
- package/convex/cloud/workflows/crudBoard.ts +217 -0
- package/convex/cloud/workflows/crudKSAs.ts +262 -0
- package/convex/cloud/workflows/crudLorobeads.ts +371 -0
- package/convex/cloud/workflows/crudSkills.ts +205 -0
- package/convex/cloud/workflows/crudThreads.ts +708 -0
- package/convex/cloud/workflows/lifecycleSandbox.ts +1396 -0
- package/convex/cloud/workflows/sandboxConvex.ts +1046 -0
- package/convex/sandbox/README.md +90 -0
- package/convex/sandbox/_generated/api.d.ts +2934 -0
- package/convex/sandbox/_generated/api.js +23 -0
- package/convex/sandbox/_generated/dataModel.d.ts +60 -0
- package/convex/sandbox/_generated/server.d.ts +143 -0
- package/convex/sandbox/_generated/server.js +93 -0
- package/convex/sandbox/actions/bash.ts +130 -0
- package/convex/sandbox/actions/browser.ts +282 -0
- package/convex/sandbox/actions/file.ts +336 -0
- package/convex/sandbox/actions/lsp.ts +325 -0
- package/convex/sandbox/actions/pdf.ts +119 -0
- package/convex/sandbox/agent/codeExecLoop.ts +535 -0
- package/convex/sandbox/agent/decisions.ts +284 -0
- package/convex/sandbox/agent/index.ts +515 -0
- package/convex/sandbox/agent/subagents.ts +651 -0
- package/convex/sandbox/brandResearch/index.ts +417 -0
- package/convex/sandbox/context/index.ts +7 -0
- package/convex/sandbox/context/session.ts +402 -0
- package/convex/sandbox/convex.config.ts +17 -0
- package/convex/sandbox/index.ts +51 -0
- package/convex/sandbox/nodeActions/codeExec.ts +130 -0
- package/convex/sandbox/planning/beads.ts +187 -0
- package/convex/sandbox/planning/index.ts +8 -0
- package/convex/sandbox/planning/sync.ts +194 -0
- package/convex/sandbox/prompts/codeExec.ts +852 -0
- package/convex/sandbox/prompts/modes.ts +231 -0
- package/convex/sandbox/prompts/system.ts +142 -0
- package/convex/sandbox/schema.ts +510 -0
- package/convex/sandbox/state/artifacts.ts +99 -0
- package/convex/sandbox/state/checkpoints.ts +341 -0
- package/convex/sandbox/state/files.ts +383 -0
- package/convex/sandbox/state/index.ts +10 -0
- package/convex/sandbox/state/verification.actions.ts +268 -0
- package/convex/sandbox/state/verification.ts +101 -0
- package/convex/sandbox/tsconfig.json +25 -0
- package/convex/sandbox/utils/codeExecHelpers.ts +52 -0
- package/dist/cli/commands/build.d.ts +19 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +223 -0
- package/dist/cli/commands/init.d.ts +16 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +148 -0
- package/dist/cli/commands/publish.d.ts +12 -0
- package/dist/cli/commands/publish.d.ts.map +1 -0
- package/dist/cli/commands/publish.js +33 -0
- package/dist/cli/index.d.ts +14 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +40 -0
- package/dist/sdk/builders.d.ts +104 -0
- package/dist/sdk/builders.d.ts.map +1 -0
- package/dist/sdk/builders.js +214 -0
- package/dist/sdk/index.d.ts +29 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +38 -0
- package/dist/sdk/types.d.ts +107 -0
- package/dist/sdk/types.d.ts.map +1 -0
- package/dist/sdk/types.js +6 -0
- package/ksa/README.md +263 -0
- package/ksa/_generated/REFERENCE.md +2954 -0
- package/ksa/_generated/registry.ts +257 -0
- package/ksa/_shared/configReader.ts +302 -0
- package/ksa/_shared/configSchemas.ts +649 -0
- package/ksa/_shared/gateway.ts +175 -0
- package/ksa/_shared/ksaBehaviors.ts +411 -0
- package/ksa/_shared/ksaProxy.ts +248 -0
- package/ksa/_shared/localDb.ts +302 -0
- package/ksa/index.ts +134 -0
- package/package.json +93 -0
- package/runtime/browser/agent-browser.ts +330 -0
- package/runtime/entrypoint.ts +194 -0
- package/runtime/lsp/manager.ts +366 -0
- package/runtime/pdf/pdf-generator.ts +50 -0
- package/runtime/pdf/renderer.ts +357 -0
- package/runtime/pdf/schema.ts +97 -0
- package/runtime/services/file-watcher.ts +191 -0
- package/template/build.ts +307 -0
- package/template/e2b/Dockerfile +69 -0
- package/template/e2b/e2b.toml +13 -0
- package/template/e2b/prebuild.sh +68 -0
- package/template/e2b/start.sh +14 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent Schema Types
|
|
3
|
+
*
|
|
4
|
+
* Defines the structure for pre-analyzing user requests before sandbox execution.
|
|
5
|
+
* The Intent Schema guides the agent by providing:
|
|
6
|
+
* - Prioritized KSA selection
|
|
7
|
+
* - Structured goals and deliverables
|
|
8
|
+
* - User-configurable policies
|
|
9
|
+
*
|
|
10
|
+
* Similar to how STAGES work in boards, but dynamic and per-request.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { v } from "convex/values";
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Core Types
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Importance level for goals
|
|
21
|
+
*/
|
|
22
|
+
export type GoalImportance = "critical" | "important" | "nice-to-have";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Confidence level for schema generation
|
|
26
|
+
*/
|
|
27
|
+
export type SchemaConfidence = "high" | "medium" | "low";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Deliverable output types
|
|
31
|
+
*/
|
|
32
|
+
export type DeliverableType =
|
|
33
|
+
| "markdown"
|
|
34
|
+
| "json"
|
|
35
|
+
| "csv"
|
|
36
|
+
| "pdf"
|
|
37
|
+
| "html"
|
|
38
|
+
| "code"
|
|
39
|
+
| "image"
|
|
40
|
+
| "email";
|
|
41
|
+
|
|
42
|
+
// ============================================================================
|
|
43
|
+
// Intent Schema Structure
|
|
44
|
+
// ============================================================================
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Breakdown of user intent
|
|
48
|
+
*/
|
|
49
|
+
export interface IntentBreakdown {
|
|
50
|
+
/** One-line summary of the request */
|
|
51
|
+
summary: string;
|
|
52
|
+
/** What the user wants to accomplish */
|
|
53
|
+
objective: string;
|
|
54
|
+
/** Key context elements extracted from the request */
|
|
55
|
+
context: string[];
|
|
56
|
+
/** Detected domain/topic area */
|
|
57
|
+
domain?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* KSA prioritization and selection
|
|
62
|
+
*/
|
|
63
|
+
export interface KSAPrioritization {
|
|
64
|
+
/** KSAs to import and use first (ordered by priority) */
|
|
65
|
+
priority: string[];
|
|
66
|
+
/** KSAs that may be useful as secondary options */
|
|
67
|
+
secondary: string[];
|
|
68
|
+
/** KSAs explicitly not relevant for this request */
|
|
69
|
+
notNeeded: string[];
|
|
70
|
+
/** Reasoning for these choices */
|
|
71
|
+
reasoning: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* A goal for the agent to accomplish
|
|
76
|
+
*/
|
|
77
|
+
export interface IntentGoal {
|
|
78
|
+
/** Unique identifier */
|
|
79
|
+
id: string;
|
|
80
|
+
/** Goal description */
|
|
81
|
+
text: string;
|
|
82
|
+
/** How important is this goal */
|
|
83
|
+
importance: GoalImportance;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A deliverable the agent should produce
|
|
88
|
+
*/
|
|
89
|
+
export interface IntentDeliverable {
|
|
90
|
+
/** Unique identifier */
|
|
91
|
+
id: string;
|
|
92
|
+
/** Output format type */
|
|
93
|
+
type: DeliverableType;
|
|
94
|
+
/** Name of the deliverable */
|
|
95
|
+
name: string;
|
|
96
|
+
/** Description of what should be in it */
|
|
97
|
+
description: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Suggested execution plan
|
|
102
|
+
*/
|
|
103
|
+
export interface IntentPlan {
|
|
104
|
+
/** Goals to accomplish */
|
|
105
|
+
goals: IntentGoal[];
|
|
106
|
+
/** Deliverables to produce */
|
|
107
|
+
deliverables: IntentDeliverable[];
|
|
108
|
+
/** High-level execution steps */
|
|
109
|
+
steps: string[];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Policy controls (user-adjustable)
|
|
114
|
+
*/
|
|
115
|
+
export interface IntentPolicy {
|
|
116
|
+
/** KSAs that are enabled for this request */
|
|
117
|
+
enabledKSAs: string[];
|
|
118
|
+
/** KSAs explicitly blocked by user */
|
|
119
|
+
disabledKSAs: string[];
|
|
120
|
+
/** Maximum iterations/loops allowed */
|
|
121
|
+
maxIterations?: number;
|
|
122
|
+
/** Whether external API calls are allowed */
|
|
123
|
+
allowExternalCalls: boolean;
|
|
124
|
+
/** KSAs that require user approval before use */
|
|
125
|
+
requireApprovalFor?: string[];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Metadata about schema generation
|
|
130
|
+
*/
|
|
131
|
+
export interface IntentSchemaMeta {
|
|
132
|
+
/** Model used for generation */
|
|
133
|
+
model: string;
|
|
134
|
+
/** When the schema was generated */
|
|
135
|
+
generatedAt: number;
|
|
136
|
+
/** Confidence in the schema accuracy */
|
|
137
|
+
confidence: SchemaConfidence;
|
|
138
|
+
/** Generation latency in ms */
|
|
139
|
+
latencyMs?: number;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Complete Intent Schema
|
|
144
|
+
*
|
|
145
|
+
* Pre-analyzed structure that guides agent execution.
|
|
146
|
+
* Generated by a fast LLM (GROQ) while sandbox is warming up.
|
|
147
|
+
*/
|
|
148
|
+
export interface IntentSchema {
|
|
149
|
+
/** Breakdown of user intent */
|
|
150
|
+
intent: IntentBreakdown;
|
|
151
|
+
/** KSA prioritization and selection */
|
|
152
|
+
ksas: KSAPrioritization;
|
|
153
|
+
/** Suggested execution plan */
|
|
154
|
+
plan: IntentPlan;
|
|
155
|
+
/** Policy controls */
|
|
156
|
+
policy: IntentPolicy;
|
|
157
|
+
/** Generation metadata */
|
|
158
|
+
meta: IntentSchemaMeta;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// ============================================================================
|
|
162
|
+
// User Policy Configuration
|
|
163
|
+
// ============================================================================
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* User-configurable policy settings
|
|
167
|
+
* Stored in user settings, applied to all agent requests
|
|
168
|
+
*/
|
|
169
|
+
export interface UserAgentPolicy {
|
|
170
|
+
/** KSAs the user has disabled globally */
|
|
171
|
+
disabledKSAs: string[];
|
|
172
|
+
/** KSAs that require approval before use */
|
|
173
|
+
requireApprovalFor: string[];
|
|
174
|
+
/** Blocked deliverable types (e.g., no emails) */
|
|
175
|
+
blockedDeliverableTypes: DeliverableType[];
|
|
176
|
+
/** Budget limit per request (in tokens) */
|
|
177
|
+
maxCostPerRequest?: number;
|
|
178
|
+
/** Whether to allow external API calls by default */
|
|
179
|
+
allowExternalCalls: boolean;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Default user policy - all KSAs except brandscan and boards
|
|
184
|
+
* These are powerful app-level KSAs that should be explicitly enabled.
|
|
185
|
+
*/
|
|
186
|
+
export const DEFAULT_USER_POLICY: UserAgentPolicy = {
|
|
187
|
+
disabledKSAs: ["brandscan", "boards"],
|
|
188
|
+
requireApprovalFor: ["email"], // Email sending requires approval by default
|
|
189
|
+
blockedDeliverableTypes: [],
|
|
190
|
+
allowExternalCalls: true,
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// ============================================================================
|
|
194
|
+
// Convex Validators
|
|
195
|
+
// ============================================================================
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Convex validator for IntentSchema
|
|
199
|
+
*/
|
|
200
|
+
export const intentSchemaValidator = v.object({
|
|
201
|
+
intent: v.object({
|
|
202
|
+
summary: v.string(),
|
|
203
|
+
objective: v.string(),
|
|
204
|
+
context: v.array(v.string()),
|
|
205
|
+
domain: v.optional(v.string()),
|
|
206
|
+
}),
|
|
207
|
+
ksas: v.object({
|
|
208
|
+
priority: v.array(v.string()),
|
|
209
|
+
secondary: v.array(v.string()),
|
|
210
|
+
notNeeded: v.array(v.string()),
|
|
211
|
+
reasoning: v.string(),
|
|
212
|
+
}),
|
|
213
|
+
plan: v.object({
|
|
214
|
+
goals: v.array(
|
|
215
|
+
v.object({
|
|
216
|
+
id: v.string(),
|
|
217
|
+
text: v.string(),
|
|
218
|
+
importance: v.union(
|
|
219
|
+
v.literal("critical"),
|
|
220
|
+
v.literal("important"),
|
|
221
|
+
v.literal("nice-to-have")
|
|
222
|
+
),
|
|
223
|
+
})
|
|
224
|
+
),
|
|
225
|
+
deliverables: v.array(
|
|
226
|
+
v.object({
|
|
227
|
+
id: v.string(),
|
|
228
|
+
type: v.union(
|
|
229
|
+
v.literal("markdown"),
|
|
230
|
+
v.literal("json"),
|
|
231
|
+
v.literal("csv"),
|
|
232
|
+
v.literal("pdf"),
|
|
233
|
+
v.literal("html"),
|
|
234
|
+
v.literal("code"),
|
|
235
|
+
v.literal("image"),
|
|
236
|
+
v.literal("email")
|
|
237
|
+
),
|
|
238
|
+
name: v.string(),
|
|
239
|
+
description: v.string(),
|
|
240
|
+
})
|
|
241
|
+
),
|
|
242
|
+
steps: v.array(v.string()),
|
|
243
|
+
}),
|
|
244
|
+
policy: v.object({
|
|
245
|
+
enabledKSAs: v.array(v.string()),
|
|
246
|
+
disabledKSAs: v.array(v.string()),
|
|
247
|
+
maxIterations: v.optional(v.number()),
|
|
248
|
+
allowExternalCalls: v.boolean(),
|
|
249
|
+
requireApprovalFor: v.optional(v.array(v.string())),
|
|
250
|
+
}),
|
|
251
|
+
meta: v.object({
|
|
252
|
+
model: v.string(),
|
|
253
|
+
generatedAt: v.number(),
|
|
254
|
+
confidence: v.union(
|
|
255
|
+
v.literal("high"),
|
|
256
|
+
v.literal("medium"),
|
|
257
|
+
v.literal("low")
|
|
258
|
+
),
|
|
259
|
+
latencyMs: v.optional(v.number()),
|
|
260
|
+
}),
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Convex validator for UserAgentPolicy
|
|
265
|
+
*/
|
|
266
|
+
export const userAgentPolicyValidator = v.object({
|
|
267
|
+
disabledKSAs: v.array(v.string()),
|
|
268
|
+
requireApprovalFor: v.array(v.string()),
|
|
269
|
+
blockedDeliverableTypes: v.array(
|
|
270
|
+
v.union(
|
|
271
|
+
v.literal("markdown"),
|
|
272
|
+
v.literal("json"),
|
|
273
|
+
v.literal("csv"),
|
|
274
|
+
v.literal("pdf"),
|
|
275
|
+
v.literal("html"),
|
|
276
|
+
v.literal("code"),
|
|
277
|
+
v.literal("image"),
|
|
278
|
+
v.literal("email")
|
|
279
|
+
)
|
|
280
|
+
),
|
|
281
|
+
maxCostPerRequest: v.optional(v.number()),
|
|
282
|
+
allowExternalCalls: v.boolean(),
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// ============================================================================
|
|
286
|
+
// Helper Functions
|
|
287
|
+
// ============================================================================
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Create an empty/default Intent Schema
|
|
291
|
+
*/
|
|
292
|
+
export function createDefaultIntentSchema(
|
|
293
|
+
prompt: string,
|
|
294
|
+
enabledKSAs: string[]
|
|
295
|
+
): IntentSchema {
|
|
296
|
+
return {
|
|
297
|
+
intent: {
|
|
298
|
+
summary: prompt.slice(0, 100),
|
|
299
|
+
objective: "Process user request",
|
|
300
|
+
context: [],
|
|
301
|
+
},
|
|
302
|
+
ksas: {
|
|
303
|
+
priority: enabledKSAs.slice(0, 3),
|
|
304
|
+
secondary: enabledKSAs.slice(3),
|
|
305
|
+
notNeeded: [],
|
|
306
|
+
reasoning: "Default schema - no pre-analysis performed",
|
|
307
|
+
},
|
|
308
|
+
plan: {
|
|
309
|
+
goals: [
|
|
310
|
+
{
|
|
311
|
+
id: "g1",
|
|
312
|
+
text: "Complete the user's request",
|
|
313
|
+
importance: "critical",
|
|
314
|
+
},
|
|
315
|
+
],
|
|
316
|
+
deliverables: [],
|
|
317
|
+
steps: ["Analyze request", "Execute", "Return results"],
|
|
318
|
+
},
|
|
319
|
+
policy: {
|
|
320
|
+
enabledKSAs,
|
|
321
|
+
disabledKSAs: [],
|
|
322
|
+
allowExternalCalls: true,
|
|
323
|
+
},
|
|
324
|
+
meta: {
|
|
325
|
+
model: "default",
|
|
326
|
+
generatedAt: Date.now(),
|
|
327
|
+
confidence: "low",
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Merge user policy with generated schema policy
|
|
334
|
+
*/
|
|
335
|
+
export function applyUserPolicy(
|
|
336
|
+
schema: IntentSchema,
|
|
337
|
+
userPolicy: Partial<UserAgentPolicy>
|
|
338
|
+
): IntentSchema {
|
|
339
|
+
const merged = { ...schema };
|
|
340
|
+
|
|
341
|
+
// Apply disabled KSAs from user policy
|
|
342
|
+
if (userPolicy.disabledKSAs?.length) {
|
|
343
|
+
merged.policy.disabledKSAs = [
|
|
344
|
+
...new Set([
|
|
345
|
+
...merged.policy.disabledKSAs,
|
|
346
|
+
...userPolicy.disabledKSAs,
|
|
347
|
+
]),
|
|
348
|
+
];
|
|
349
|
+
// Remove disabled KSAs from enabled list
|
|
350
|
+
merged.policy.enabledKSAs = merged.policy.enabledKSAs.filter(
|
|
351
|
+
(k) => !merged.policy.disabledKSAs.includes(k)
|
|
352
|
+
);
|
|
353
|
+
// Remove from priority lists
|
|
354
|
+
merged.ksas.priority = merged.ksas.priority.filter(
|
|
355
|
+
(k) => !merged.policy.disabledKSAs.includes(k)
|
|
356
|
+
);
|
|
357
|
+
merged.ksas.secondary = merged.ksas.secondary.filter(
|
|
358
|
+
(k) => !merged.policy.disabledKSAs.includes(k)
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Apply approval requirements
|
|
363
|
+
if (userPolicy.requireApprovalFor?.length) {
|
|
364
|
+
merged.policy.requireApprovalFor = userPolicy.requireApprovalFor;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Apply external calls setting
|
|
368
|
+
if (userPolicy.allowExternalCalls !== undefined) {
|
|
369
|
+
merged.policy.allowExternalCalls = userPolicy.allowExternalCalls;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Filter blocked deliverable types
|
|
373
|
+
if (userPolicy.blockedDeliverableTypes?.length) {
|
|
374
|
+
merged.plan.deliverables = merged.plan.deliverables.filter(
|
|
375
|
+
(d) => !userPolicy.blockedDeliverableTypes!.includes(d.type)
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return merged;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Validate that a parsed schema has all required fields
|
|
384
|
+
*/
|
|
385
|
+
export function validateIntentSchema(obj: unknown): obj is IntentSchema {
|
|
386
|
+
if (!obj || typeof obj !== "object") return false;
|
|
387
|
+
|
|
388
|
+
const schema = obj as Record<string, unknown>;
|
|
389
|
+
|
|
390
|
+
// Check top-level fields
|
|
391
|
+
if (!schema.intent || typeof schema.intent !== "object") return false;
|
|
392
|
+
if (!schema.ksas || typeof schema.ksas !== "object") return false;
|
|
393
|
+
if (!schema.plan || typeof schema.plan !== "object") return false;
|
|
394
|
+
if (!schema.policy || typeof schema.policy !== "object") return false;
|
|
395
|
+
|
|
396
|
+
// Check intent fields
|
|
397
|
+
const intent = schema.intent as Record<string, unknown>;
|
|
398
|
+
if (typeof intent.summary !== "string") return false;
|
|
399
|
+
if (typeof intent.objective !== "string") return false;
|
|
400
|
+
if (!Array.isArray(intent.context)) return false;
|
|
401
|
+
|
|
402
|
+
// Check ksas fields
|
|
403
|
+
const ksas = schema.ksas as Record<string, unknown>;
|
|
404
|
+
if (!Array.isArray(ksas.priority)) return false;
|
|
405
|
+
if (!Array.isArray(ksas.secondary)) return false;
|
|
406
|
+
|
|
407
|
+
// Check plan fields
|
|
408
|
+
const plan = schema.plan as Record<string, unknown>;
|
|
409
|
+
if (!Array.isArray(plan.goals)) return false;
|
|
410
|
+
if (!Array.isArray(plan.deliverables)) return false;
|
|
411
|
+
if (!Array.isArray(plan.steps)) return false;
|
|
412
|
+
|
|
413
|
+
// Check policy fields
|
|
414
|
+
const policy = schema.policy as Record<string, unknown>;
|
|
415
|
+
if (!Array.isArray(policy.enabledKSAs)) return false;
|
|
416
|
+
|
|
417
|
+
return true;
|
|
418
|
+
}
|