@contractspec/module.ai-chat 4.3.6 → 4.3.7

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.
Files changed (46) hide show
  1. package/README.md +62 -370
  2. package/dist/adapters/ai-sdk-bundle-adapter.d.ts +1 -1
  3. package/dist/adapters/index.d.ts +1 -1
  4. package/dist/browser/context/index.js +93 -93
  5. package/dist/browser/core/index.js +308 -307
  6. package/dist/browser/index.js +3803 -3801
  7. package/dist/browser/presentation/components/index.js +2617 -2618
  8. package/dist/browser/presentation/hooks/index.js +476 -476
  9. package/dist/browser/presentation/index.js +2474 -2475
  10. package/dist/browser/providers/index.js +7 -7
  11. package/dist/context/index.d.ts +1 -1
  12. package/dist/context/index.js +93 -93
  13. package/dist/core/agent-tools-adapter.d.ts +1 -1
  14. package/dist/core/chat-service.d.ts +4 -4
  15. package/dist/core/create-chat-route.d.ts +1 -1
  16. package/dist/core/create-completion-route.d.ts +15 -0
  17. package/dist/core/export-formatters.d.ts +1 -1
  18. package/dist/core/index.d.ts +6 -6
  19. package/dist/core/index.js +308 -307
  20. package/dist/core/local-storage-conversation-store.d.ts +1 -1
  21. package/dist/core/surface-planner-tools.d.ts +2 -2
  22. package/dist/core/workflow-tools.d.ts +1 -1
  23. package/dist/index.d.ts +8 -8
  24. package/dist/index.js +3803 -3801
  25. package/dist/node/context/index.js +93 -93
  26. package/dist/node/core/index.js +308 -307
  27. package/dist/node/index.js +3803 -3801
  28. package/dist/node/presentation/components/index.js +2617 -2618
  29. package/dist/node/presentation/hooks/index.js +476 -476
  30. package/dist/node/presentation/index.js +2474 -2475
  31. package/dist/node/providers/index.js +7 -7
  32. package/dist/presentation/components/ChainOfThought.d.ts +1 -1
  33. package/dist/presentation/components/ChatExportToolbar.d.ts +1 -1
  34. package/dist/presentation/components/ChatSidebar.d.ts +1 -1
  35. package/dist/presentation/components/ChatWithExport.d.ts +1 -1
  36. package/dist/presentation/components/index.d.ts +11 -11
  37. package/dist/presentation/components/index.js +2617 -2618
  38. package/dist/presentation/hooks/index.d.ts +4 -4
  39. package/dist/presentation/hooks/index.js +476 -476
  40. package/dist/presentation/hooks/useChat.d.ts +6 -6
  41. package/dist/presentation/hooks/useConversations.d.ts +1 -1
  42. package/dist/presentation/hooks/useProviders.d.ts +1 -1
  43. package/dist/presentation/index.js +2474 -2475
  44. package/dist/providers/index.d.ts +2 -2
  45. package/dist/providers/index.js +7 -7
  46. package/package.json +10 -10
@@ -5,6 +5,113 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
5
5
  return require.apply(this, arguments);
6
6
  throw Error('Dynamic require of "' + x + '" is not supported');
7
7
  });
8
+
9
+ // src/core/agent-adapter.ts
10
+ function createChatAgentAdapter(agent) {
11
+ return {
12
+ async generate({ prompt, signal }) {
13
+ const result = await agent.generate({ prompt, signal });
14
+ return {
15
+ text: result.text,
16
+ toolCalls: result.toolCalls,
17
+ toolResults: result.toolResults,
18
+ usage: result.usage
19
+ };
20
+ }
21
+ };
22
+ }
23
+ // src/core/agent-tools-adapter.ts
24
+ import { tool } from "ai";
25
+ import { z } from "zod";
26
+ function getInputSchema(_schema) {
27
+ return z.object({}).passthrough();
28
+ }
29
+ function agentToolConfigsToToolSet(configs, handlers) {
30
+ const result = {};
31
+ for (const config of configs) {
32
+ const handler = handlers?.[config.name];
33
+ const inputSchema = getInputSchema(config.schema);
34
+ result[config.name] = tool({
35
+ description: config.description ?? config.name,
36
+ inputSchema,
37
+ execute: async (input) => {
38
+ if (!handler) {
39
+ return {
40
+ status: "unimplemented",
41
+ message: "Wire handler in host",
42
+ toolName: config.name
43
+ };
44
+ }
45
+ try {
46
+ const output = await Promise.resolve(handler(input));
47
+ return typeof output === "string" ? output : output;
48
+ } catch (err) {
49
+ return {
50
+ status: "error",
51
+ error: err instanceof Error ? err.message : String(err),
52
+ toolName: config.name
53
+ };
54
+ }
55
+ }
56
+ });
57
+ }
58
+ return result;
59
+ }
60
+ // src/core/chat-service.ts
61
+ import { generateText, streamText } from "ai";
62
+ import { compilePlannerPrompt } from "@contractspec/lib.surface-runtime/runtime/planner-prompt";
63
+
64
+ // src/core/contracts-context.ts
65
+ function buildContractsContextPrompt(config) {
66
+ const parts = [];
67
+ if (!config.agentSpecs?.length && !config.dataViewSpecs?.length && !config.formSpecs?.length && !config.presentationSpecs?.length && !config.operationRefs?.length) {
68
+ return "";
69
+ }
70
+ parts.push(`
71
+
72
+ ## Available resources`);
73
+ if (config.agentSpecs?.length) {
74
+ parts.push(`
75
+ ### Agent tools`);
76
+ for (const agent of config.agentSpecs) {
77
+ const toolNames = agent.tools?.map((t) => t.name).join(", ") ?? "none";
78
+ parts.push(`- **${agent.key}**: tools: ${toolNames}`);
79
+ }
80
+ }
81
+ if (config.dataViewSpecs?.length) {
82
+ parts.push(`
83
+ ### Data views`);
84
+ for (const dv of config.dataViewSpecs) {
85
+ parts.push(`- **${dv.key}**: ${dv.meta.title ?? dv.key}`);
86
+ }
87
+ }
88
+ if (config.formSpecs?.length) {
89
+ parts.push(`
90
+ ### Forms`);
91
+ for (const form of config.formSpecs) {
92
+ parts.push(`- **${form.key}**: ${form.meta.title ?? form.key}`);
93
+ }
94
+ }
95
+ if (config.presentationSpecs?.length) {
96
+ parts.push(`
97
+ ### Presentations`);
98
+ for (const pres of config.presentationSpecs) {
99
+ parts.push(`- **${pres.key}**: ${pres.meta.title ?? pres.key} (targets: ${pres.targets?.join(", ") ?? "react"})`);
100
+ }
101
+ }
102
+ if (config.operationRefs?.length) {
103
+ parts.push(`
104
+ ### Operations`);
105
+ for (const op of config.operationRefs) {
106
+ parts.push(`- **${op.key}@${op.version}**`);
107
+ }
108
+ }
109
+ parts.push(`
110
+ Use the available tools to invoke operations, query data views, or propose surface changes when appropriate.`);
111
+ return parts.join(`
112
+ `);
113
+ }
114
+
8
115
  // src/core/conversation-store.ts
9
116
  function generateId(prefix) {
10
117
  return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
@@ -165,8 +272,163 @@ class InMemoryConversationStore {
165
272
  function createInMemoryConversationStore() {
166
273
  return new InMemoryConversationStore;
167
274
  }
168
- // src/core/chat-service.ts
169
- import { generateText, streamText } from "ai";
275
+
276
+ // src/core/surface-planner-tools.ts
277
+ import { buildSurfacePatchProposal } from "@contractspec/lib.surface-runtime/runtime/planner-tools";
278
+ import {
279
+ validatePatchProposal
280
+ } from "@contractspec/lib.surface-runtime/spec/validate-surface-patch";
281
+ import { tool as tool2 } from "ai";
282
+ import { z as z2 } from "zod";
283
+ var VALID_OPS = [
284
+ "insert-node",
285
+ "replace-node",
286
+ "remove-node",
287
+ "move-node",
288
+ "resize-panel",
289
+ "set-layout",
290
+ "reveal-field",
291
+ "hide-field",
292
+ "promote-action",
293
+ "set-focus"
294
+ ];
295
+ var DEFAULT_NODE_KINDS = [
296
+ "entity-section",
297
+ "entity-card",
298
+ "data-view",
299
+ "assistant-panel",
300
+ "chat-thread",
301
+ "action-bar",
302
+ "timeline",
303
+ "table",
304
+ "rich-doc",
305
+ "form",
306
+ "chart",
307
+ "custom-widget"
308
+ ];
309
+ function collectSlotIdsFromRegion(node) {
310
+ const ids = [];
311
+ if (node.type === "slot") {
312
+ ids.push(node.slotId);
313
+ }
314
+ if (node.type === "panel-group" || node.type === "stack") {
315
+ for (const child of node.children) {
316
+ ids.push(...collectSlotIdsFromRegion(child));
317
+ }
318
+ }
319
+ if (node.type === "tabs") {
320
+ for (const tab of node.tabs) {
321
+ ids.push(...collectSlotIdsFromRegion(tab.child));
322
+ }
323
+ }
324
+ if (node.type === "floating") {
325
+ ids.push(node.anchorSlotId);
326
+ ids.push(...collectSlotIdsFromRegion(node.child));
327
+ }
328
+ return ids;
329
+ }
330
+ function deriveConstraints(plan) {
331
+ const slotIds = collectSlotIdsFromRegion(plan.layoutRoot);
332
+ const uniqueSlots = [...new Set(slotIds)];
333
+ return {
334
+ allowedOps: VALID_OPS,
335
+ allowedSlots: uniqueSlots.length > 0 ? uniqueSlots : ["assistant", "primary"],
336
+ allowedNodeKinds: DEFAULT_NODE_KINDS
337
+ };
338
+ }
339
+ var ProposePatchInputSchema = z2.object({
340
+ proposalId: z2.string().describe("Unique proposal identifier"),
341
+ ops: z2.array(z2.object({
342
+ op: z2.enum([
343
+ "insert-node",
344
+ "replace-node",
345
+ "remove-node",
346
+ "move-node",
347
+ "resize-panel",
348
+ "set-layout",
349
+ "reveal-field",
350
+ "hide-field",
351
+ "promote-action",
352
+ "set-focus"
353
+ ]),
354
+ slotId: z2.string().optional(),
355
+ nodeId: z2.string().optional(),
356
+ toSlotId: z2.string().optional(),
357
+ index: z2.number().optional(),
358
+ node: z2.object({
359
+ nodeId: z2.string(),
360
+ kind: z2.string(),
361
+ title: z2.string().optional(),
362
+ props: z2.record(z2.string(), z2.unknown()).optional(),
363
+ children: z2.array(z2.unknown()).optional()
364
+ }).optional(),
365
+ persistKey: z2.string().optional(),
366
+ sizes: z2.array(z2.number()).optional(),
367
+ layoutId: z2.string().optional(),
368
+ fieldId: z2.string().optional(),
369
+ actionId: z2.string().optional(),
370
+ placement: z2.enum(["header", "inline", "context", "assistant"]).optional(),
371
+ targetId: z2.string().optional()
372
+ }))
373
+ });
374
+ function createSurfacePlannerTools(config) {
375
+ const { plan, constraints, onPatchProposal } = config;
376
+ const resolvedConstraints = constraints ?? deriveConstraints(plan);
377
+ const proposePatchTool = tool2({
378
+ description: "Propose surface patches (layout changes, node insertions, etc.) for user approval. " + "Only use allowed ops, slots, and node kinds from the planner context.",
379
+ inputSchema: ProposePatchInputSchema,
380
+ execute: async (input) => {
381
+ const ops = input.ops;
382
+ try {
383
+ validatePatchProposal(ops, resolvedConstraints);
384
+ const proposal = buildSurfacePatchProposal(input.proposalId, ops);
385
+ onPatchProposal?.(proposal);
386
+ return {
387
+ success: true,
388
+ proposalId: proposal.proposalId,
389
+ opsCount: proposal.ops.length,
390
+ message: "Patch proposal validated; awaiting user approval"
391
+ };
392
+ } catch (err) {
393
+ return {
394
+ success: false,
395
+ error: err instanceof Error ? err.message : String(err),
396
+ proposalId: input.proposalId
397
+ };
398
+ }
399
+ }
400
+ });
401
+ return {
402
+ "propose-patch": proposePatchTool
403
+ };
404
+ }
405
+ function buildPlannerPromptInput(plan) {
406
+ const constraints = deriveConstraints(plan);
407
+ return {
408
+ bundleMeta: {
409
+ key: plan.bundleKey,
410
+ version: "0.0.0",
411
+ title: plan.bundleKey
412
+ },
413
+ surfaceId: plan.surfaceId,
414
+ allowedPatchOps: constraints.allowedOps,
415
+ allowedSlots: [...constraints.allowedSlots],
416
+ allowedNodeKinds: [...constraints.allowedNodeKinds],
417
+ actions: plan.actions.map((a) => ({
418
+ actionId: a.actionId,
419
+ title: a.title
420
+ })),
421
+ preferences: {
422
+ guidance: "hints",
423
+ density: "standard",
424
+ dataDepth: "detailed",
425
+ control: "standard",
426
+ media: "text",
427
+ pace: "balanced",
428
+ narrative: "top-down"
429
+ }
430
+ };
431
+ }
170
432
 
171
433
  // src/core/thinking-levels.ts
172
434
  var THINKING_LEVEL_LABELS = {
@@ -220,50 +482,50 @@ function getProviderOptions(level, providerName) {
220
482
  }
221
483
 
222
484
  // src/core/workflow-tools.ts
223
- import { tool } from "ai";
224
- import { z } from "zod";
225
485
  import {
226
- WorkflowComposer,
227
- validateExtension
486
+ validateExtension,
487
+ WorkflowComposer
228
488
  } from "@contractspec/lib.workflow-composer";
229
- var StepTypeSchema = z.enum(["human", "automation", "decision"]);
230
- var StepActionSchema = z.object({
231
- operation: z.object({
232
- name: z.string(),
233
- version: z.number()
489
+ import { tool as tool3 } from "ai";
490
+ import { z as z3 } from "zod";
491
+ var StepTypeSchema = z3.enum(["human", "automation", "decision"]);
492
+ var StepActionSchema = z3.object({
493
+ operation: z3.object({
494
+ name: z3.string(),
495
+ version: z3.number()
234
496
  }).optional(),
235
- form: z.object({
236
- key: z.string(),
237
- version: z.number()
497
+ form: z3.object({
498
+ key: z3.string(),
499
+ version: z3.number()
238
500
  }).optional()
239
501
  }).optional();
240
- var StepSchema = z.object({
241
- id: z.string(),
502
+ var StepSchema = z3.object({
503
+ id: z3.string(),
242
504
  type: StepTypeSchema,
243
- label: z.string(),
244
- description: z.string().optional(),
505
+ label: z3.string(),
506
+ description: z3.string().optional(),
245
507
  action: StepActionSchema
246
508
  });
247
- var StepInjectionSchema = z.object({
248
- after: z.string().optional(),
249
- before: z.string().optional(),
509
+ var StepInjectionSchema = z3.object({
510
+ after: z3.string().optional(),
511
+ before: z3.string().optional(),
250
512
  inject: StepSchema,
251
- transitionTo: z.string().optional(),
252
- transitionFrom: z.string().optional(),
253
- when: z.string().optional()
513
+ transitionTo: z3.string().optional(),
514
+ transitionFrom: z3.string().optional(),
515
+ when: z3.string().optional()
254
516
  });
255
- var WorkflowExtensionInputSchema = z.object({
256
- workflow: z.string(),
257
- tenantId: z.string().optional(),
258
- role: z.string().optional(),
259
- priority: z.number().optional(),
260
- customSteps: z.array(StepInjectionSchema).optional(),
261
- hiddenSteps: z.array(z.string()).optional()
517
+ var WorkflowExtensionInputSchema = z3.object({
518
+ workflow: z3.string(),
519
+ tenantId: z3.string().optional(),
520
+ role: z3.string().optional(),
521
+ priority: z3.number().optional(),
522
+ customSteps: z3.array(StepInjectionSchema).optional(),
523
+ hiddenSteps: z3.array(z3.string()).optional()
262
524
  });
263
525
  function createWorkflowTools(config) {
264
526
  const { baseWorkflows, composer } = config;
265
527
  const baseByKey = new Map(baseWorkflows.map((b) => [b.meta.key, b]));
266
- const createWorkflowExtensionTool = tool({
528
+ const createWorkflowExtensionTool = tool3({
267
529
  description: "Create or validate a workflow extension. Use when the user asks to add steps, modify a workflow, or create a tenant-specific extension. The extension targets an existing base workflow.",
268
530
  inputSchema: WorkflowExtensionInputSchema,
269
531
  execute: async (input) => {
@@ -299,13 +561,13 @@ function createWorkflowTools(config) {
299
561
  }
300
562
  }
301
563
  });
302
- const composeWorkflowInputSchema = z.object({
303
- workflowKey: z.string().describe("Base workflow meta.key"),
304
- tenantId: z.string().optional(),
305
- role: z.string().optional(),
306
- extensions: z.array(WorkflowExtensionInputSchema).optional().describe("Extensions to register before composing")
564
+ const composeWorkflowInputSchema = z3.object({
565
+ workflowKey: z3.string().describe("Base workflow meta.key"),
566
+ tenantId: z3.string().optional(),
567
+ role: z3.string().optional(),
568
+ extensions: z3.array(WorkflowExtensionInputSchema).optional().describe("Extensions to register before composing")
307
569
  });
308
- const composeWorkflowTool = tool({
570
+ const composeWorkflowTool = tool3({
309
571
  description: "Compose a workflow by applying registered extensions to a base workflow. Returns the composed WorkflowSpec.",
310
572
  inputSchema: composeWorkflowInputSchema,
311
573
  execute: async (input) => {
@@ -349,16 +611,16 @@ function createWorkflowTools(config) {
349
611
  }
350
612
  }
351
613
  });
352
- const generateWorkflowSpecCodeInputSchema = z.object({
353
- workflowKey: z.string().describe("Workflow meta.key"),
354
- composedSteps: z.array(z.object({
355
- id: z.string(),
356
- type: z.enum(["human", "automation", "decision"]),
357
- label: z.string(),
358
- description: z.string().optional()
614
+ const generateWorkflowSpecCodeInputSchema = z3.object({
615
+ workflowKey: z3.string().describe("Workflow meta.key"),
616
+ composedSteps: z3.array(z3.object({
617
+ id: z3.string(),
618
+ type: z3.enum(["human", "automation", "decision"]),
619
+ label: z3.string(),
620
+ description: z3.string().optional()
359
621
  })).optional().describe("Steps to include; if omitted, uses the base workflow")
360
622
  });
361
- const generateWorkflowSpecCodeTool = tool({
623
+ const generateWorkflowSpecCodeTool = tool3({
362
624
  description: "Generate TypeScript code for a workflow spec. Use after composing a workflow to output the spec as code the user can save.",
363
625
  inputSchema: generateWorkflowSpecCodeInputSchema,
364
626
  execute: async (input) => {
@@ -423,254 +685,7 @@ function escapeString(value) {
423
685
  return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
424
686
  }
425
687
 
426
- // src/core/contracts-context.ts
427
- function buildContractsContextPrompt(config) {
428
- const parts = [];
429
- if (!config.agentSpecs?.length && !config.dataViewSpecs?.length && !config.formSpecs?.length && !config.presentationSpecs?.length && !config.operationRefs?.length) {
430
- return "";
431
- }
432
- parts.push(`
433
-
434
- ## Available resources`);
435
- if (config.agentSpecs?.length) {
436
- parts.push(`
437
- ### Agent tools`);
438
- for (const agent of config.agentSpecs) {
439
- const toolNames = agent.tools?.map((t) => t.name).join(", ") ?? "none";
440
- parts.push(`- **${agent.key}**: tools: ${toolNames}`);
441
- }
442
- }
443
- if (config.dataViewSpecs?.length) {
444
- parts.push(`
445
- ### Data views`);
446
- for (const dv of config.dataViewSpecs) {
447
- parts.push(`- **${dv.key}**: ${dv.meta.title ?? dv.key}`);
448
- }
449
- }
450
- if (config.formSpecs?.length) {
451
- parts.push(`
452
- ### Forms`);
453
- for (const form of config.formSpecs) {
454
- parts.push(`- **${form.key}**: ${form.meta.title ?? form.key}`);
455
- }
456
- }
457
- if (config.presentationSpecs?.length) {
458
- parts.push(`
459
- ### Presentations`);
460
- for (const pres of config.presentationSpecs) {
461
- parts.push(`- **${pres.key}**: ${pres.meta.title ?? pres.key} (targets: ${pres.targets?.join(", ") ?? "react"})`);
462
- }
463
- }
464
- if (config.operationRefs?.length) {
465
- parts.push(`
466
- ### Operations`);
467
- for (const op of config.operationRefs) {
468
- parts.push(`- **${op.key}@${op.version}**`);
469
- }
470
- }
471
- parts.push(`
472
- Use the available tools to invoke operations, query data views, or propose surface changes when appropriate.`);
473
- return parts.join(`
474
- `);
475
- }
476
-
477
- // src/core/agent-tools-adapter.ts
478
- import { tool as tool2 } from "ai";
479
- import { z as z2 } from "zod";
480
- function getInputSchema(_schema) {
481
- return z2.object({}).passthrough();
482
- }
483
- function agentToolConfigsToToolSet(configs, handlers) {
484
- const result = {};
485
- for (const config of configs) {
486
- const handler = handlers?.[config.name];
487
- const inputSchema = getInputSchema(config.schema);
488
- result[config.name] = tool2({
489
- description: config.description ?? config.name,
490
- inputSchema,
491
- execute: async (input) => {
492
- if (!handler) {
493
- return {
494
- status: "unimplemented",
495
- message: "Wire handler in host",
496
- toolName: config.name
497
- };
498
- }
499
- try {
500
- const output = await Promise.resolve(handler(input));
501
- return typeof output === "string" ? output : output;
502
- } catch (err) {
503
- return {
504
- status: "error",
505
- error: err instanceof Error ? err.message : String(err),
506
- toolName: config.name
507
- };
508
- }
509
- }
510
- });
511
- }
512
- return result;
513
- }
514
-
515
- // src/core/surface-planner-tools.ts
516
- import { tool as tool3 } from "ai";
517
- import { z as z3 } from "zod";
518
- import {
519
- validatePatchProposal
520
- } from "@contractspec/lib.surface-runtime/spec/validate-surface-patch";
521
- import { buildSurfacePatchProposal } from "@contractspec/lib.surface-runtime/runtime/planner-tools";
522
- var VALID_OPS = [
523
- "insert-node",
524
- "replace-node",
525
- "remove-node",
526
- "move-node",
527
- "resize-panel",
528
- "set-layout",
529
- "reveal-field",
530
- "hide-field",
531
- "promote-action",
532
- "set-focus"
533
- ];
534
- var DEFAULT_NODE_KINDS = [
535
- "entity-section",
536
- "entity-card",
537
- "data-view",
538
- "assistant-panel",
539
- "chat-thread",
540
- "action-bar",
541
- "timeline",
542
- "table",
543
- "rich-doc",
544
- "form",
545
- "chart",
546
- "custom-widget"
547
- ];
548
- function collectSlotIdsFromRegion(node) {
549
- const ids = [];
550
- if (node.type === "slot") {
551
- ids.push(node.slotId);
552
- }
553
- if (node.type === "panel-group" || node.type === "stack") {
554
- for (const child of node.children) {
555
- ids.push(...collectSlotIdsFromRegion(child));
556
- }
557
- }
558
- if (node.type === "tabs") {
559
- for (const tab of node.tabs) {
560
- ids.push(...collectSlotIdsFromRegion(tab.child));
561
- }
562
- }
563
- if (node.type === "floating") {
564
- ids.push(node.anchorSlotId);
565
- ids.push(...collectSlotIdsFromRegion(node.child));
566
- }
567
- return ids;
568
- }
569
- function deriveConstraints(plan) {
570
- const slotIds = collectSlotIdsFromRegion(plan.layoutRoot);
571
- const uniqueSlots = [...new Set(slotIds)];
572
- return {
573
- allowedOps: VALID_OPS,
574
- allowedSlots: uniqueSlots.length > 0 ? uniqueSlots : ["assistant", "primary"],
575
- allowedNodeKinds: DEFAULT_NODE_KINDS
576
- };
577
- }
578
- var ProposePatchInputSchema = z3.object({
579
- proposalId: z3.string().describe("Unique proposal identifier"),
580
- ops: z3.array(z3.object({
581
- op: z3.enum([
582
- "insert-node",
583
- "replace-node",
584
- "remove-node",
585
- "move-node",
586
- "resize-panel",
587
- "set-layout",
588
- "reveal-field",
589
- "hide-field",
590
- "promote-action",
591
- "set-focus"
592
- ]),
593
- slotId: z3.string().optional(),
594
- nodeId: z3.string().optional(),
595
- toSlotId: z3.string().optional(),
596
- index: z3.number().optional(),
597
- node: z3.object({
598
- nodeId: z3.string(),
599
- kind: z3.string(),
600
- title: z3.string().optional(),
601
- props: z3.record(z3.string(), z3.unknown()).optional(),
602
- children: z3.array(z3.unknown()).optional()
603
- }).optional(),
604
- persistKey: z3.string().optional(),
605
- sizes: z3.array(z3.number()).optional(),
606
- layoutId: z3.string().optional(),
607
- fieldId: z3.string().optional(),
608
- actionId: z3.string().optional(),
609
- placement: z3.enum(["header", "inline", "context", "assistant"]).optional(),
610
- targetId: z3.string().optional()
611
- }))
612
- });
613
- function createSurfacePlannerTools(config) {
614
- const { plan, constraints, onPatchProposal } = config;
615
- const resolvedConstraints = constraints ?? deriveConstraints(plan);
616
- const proposePatchTool = tool3({
617
- description: "Propose surface patches (layout changes, node insertions, etc.) for user approval. " + "Only use allowed ops, slots, and node kinds from the planner context.",
618
- inputSchema: ProposePatchInputSchema,
619
- execute: async (input) => {
620
- const ops = input.ops;
621
- try {
622
- validatePatchProposal(ops, resolvedConstraints);
623
- const proposal = buildSurfacePatchProposal(input.proposalId, ops);
624
- onPatchProposal?.(proposal);
625
- return {
626
- success: true,
627
- proposalId: proposal.proposalId,
628
- opsCount: proposal.ops.length,
629
- message: "Patch proposal validated; awaiting user approval"
630
- };
631
- } catch (err) {
632
- return {
633
- success: false,
634
- error: err instanceof Error ? err.message : String(err),
635
- proposalId: input.proposalId
636
- };
637
- }
638
- }
639
- });
640
- return {
641
- "propose-patch": proposePatchTool
642
- };
643
- }
644
- function buildPlannerPromptInput(plan) {
645
- const constraints = deriveConstraints(plan);
646
- return {
647
- bundleMeta: {
648
- key: plan.bundleKey,
649
- version: "0.0.0",
650
- title: plan.bundleKey
651
- },
652
- surfaceId: plan.surfaceId,
653
- allowedPatchOps: constraints.allowedOps,
654
- allowedSlots: [...constraints.allowedSlots],
655
- allowedNodeKinds: [...constraints.allowedNodeKinds],
656
- actions: plan.actions.map((a) => ({
657
- actionId: a.actionId,
658
- title: a.title
659
- })),
660
- preferences: {
661
- guidance: "hints",
662
- density: "standard",
663
- dataDepth: "detailed",
664
- control: "standard",
665
- media: "text",
666
- pace: "balanced",
667
- narrative: "top-down"
668
- }
669
- };
670
- }
671
-
672
688
  // src/core/chat-service.ts
673
- import { compilePlannerPrompt } from "@contractspec/lib.surface-runtime/runtime/planner-prompt";
674
689
  var DEFAULT_SYSTEM_PROMPT = `You are ContractSpec AI, an expert coding assistant specialized in ContractSpec development.
675
690
 
676
691
  Your capabilities:
@@ -1612,20 +1627,6 @@ class LocalStorageConversationStore {
1612
1627
  function createLocalStorageConversationStore(storageKey) {
1613
1628
  return new LocalStorageConversationStore(storageKey);
1614
1629
  }
1615
- // src/core/agent-adapter.ts
1616
- function createChatAgentAdapter(agent) {
1617
- return {
1618
- async generate({ prompt, signal }) {
1619
- const result = await agent.generate({ prompt, signal });
1620
- return {
1621
- text: result.text,
1622
- toolCalls: result.toolCalls,
1623
- toolResults: result.toolResults,
1624
- usage: result.usage
1625
- };
1626
- }
1627
- };
1628
- }
1629
1630
  export {
1630
1631
  getProviderOptions,
1631
1632
  getExportFilename,