(spec: PromptSpec)
| 585 | // ─── Prompt assembly ──────────────────────────────────────────────────────── |
| 586 | |
| 587 | export function generatePrompt(spec: PromptSpec): string { |
| 588 | const rootName = spec.root ?? "Root"; |
| 589 | const hasTools = !!spec.tools?.length; |
| 590 | |
| 591 | // Resolve prompt flags — defaults preserve backward compat |
| 592 | const toolCalls = spec.toolCalls ?? hasTools; |
| 593 | const bindings = spec.bindings ?? toolCalls; |
| 594 | const supportsExpressions = toolCalls || bindings; |
| 595 | |
| 596 | // Detect component-level feature usage |
| 597 | const usesActionExpression = Object.values(spec.components).some((c) => |
| 598 | c.signature?.includes("ActionExpression"), |
| 599 | ); |
| 600 | |
| 601 | const parts: string[] = []; |
| 602 | |
| 603 | parts.push(spec.preamble ?? PREAMBLE); |
| 604 | parts.push(""); |
| 605 | parts.push(syntaxRules(rootName, { supportsExpressions, bindings })); |
| 606 | parts.push(""); |
| 607 | parts.push(generateComponentSignatures(spec, { toolCalls, bindings, usesActionExpression })); |
| 608 | |
| 609 | // Built-in functions — only when expressions are enabled (Query/reactive state) |
| 610 | if (supportsExpressions) { |
| 611 | parts.push(""); |
| 612 | parts.push(builtinFunctionsSection()); |
| 613 | } |
| 614 | |
| 615 | // Query + Mutation sections |
| 616 | if (toolCalls) { |
| 617 | parts.push(""); |
| 618 | parts.push(querySection()); |
| 619 | parts.push(""); |
| 620 | parts.push(mutationSection()); |
| 621 | } |
| 622 | |
| 623 | // Action section — only when components use ActionExpression (v0.5 action syntax) |
| 624 | if (usesActionExpression) { |
| 625 | parts.push(""); |
| 626 | parts.push(actionSection({ toolCalls, bindings })); |
| 627 | } |
| 628 | |
| 629 | // Interactive filters (needs both toolCalls and bindings) |
| 630 | if (toolCalls && bindings) { |
| 631 | parts.push(""); |
| 632 | parts.push(interactiveFiltersSection()); |
| 633 | } |
| 634 | |
| 635 | // Tool workflow |
| 636 | if (toolCalls) { |
| 637 | parts.push(""); |
| 638 | parts.push(toolWorkflowSection()); |
| 639 | } |
| 640 | |
| 641 | // Tools list (only if actual tools provided) |
| 642 | if (spec.tools?.length) { |
| 643 | parts.push(""); |
| 644 | parts.push(renderToolsSection(spec.tools)); |
no test coverage detected