veryfront 0.1.610 → 0.1.612

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 (33) hide show
  1. package/esm/cli/templates/manifest.d.ts +5 -0
  2. package/esm/cli/templates/manifest.js +6 -1
  3. package/esm/deno.d.ts +1 -0
  4. package/esm/deno.js +2 -1
  5. package/esm/extensions/ext-sandbox-shell-tools/src/index.d.ts.map +1 -1
  6. package/esm/extensions/ext-sandbox-shell-tools/src/index.js +1 -1
  7. package/esm/src/chat/message-prep.d.ts.map +1 -1
  8. package/esm/src/chat/message-prep.js +128 -20
  9. package/esm/src/html/styles-builder/plugin-loader.d.ts.map +1 -1
  10. package/esm/src/html/styles-builder/plugin-loader.js +8 -1
  11. package/esm/src/html/utils.d.ts.map +1 -1
  12. package/esm/src/html/utils.js +2 -0
  13. package/esm/src/integrations/_data.js +2 -2
  14. package/esm/src/integrations/_tool_summaries.d.ts +3 -0
  15. package/esm/src/integrations/_tool_summaries.d.ts.map +1 -0
  16. package/esm/src/integrations/_tool_summaries.js +6 -0
  17. package/esm/src/integrations/index.d.ts +2 -2
  18. package/esm/src/integrations/index.d.ts.map +1 -1
  19. package/esm/src/integrations/index.js +1 -1
  20. package/esm/src/integrations/schema.d.ts +136 -4
  21. package/esm/src/integrations/schema.d.ts.map +1 -1
  22. package/esm/src/integrations/schema.js +15 -0
  23. package/esm/src/integrations/types.d.ts +14 -0
  24. package/esm/src/integrations/types.d.ts.map +1 -1
  25. package/esm/src/transforms/import-rewriter/strategies/veryfront-strategy.d.ts.map +1 -1
  26. package/esm/src/transforms/import-rewriter/strategies/veryfront-strategy.js +13 -8
  27. package/esm/src/utils/version-constant.d.ts +1 -1
  28. package/esm/src/utils/version-constant.js +1 -1
  29. package/esm/src/workflow/react/use-approval.js +1 -1
  30. package/esm/src/workflow/react/use-workflow-list.js +1 -1
  31. package/esm/src/workflow/react/use-workflow-start.js +1 -1
  32. package/esm/src/workflow/react/use-workflow.js +1 -1
  33. package/package.json +1 -1
@@ -5,6 +5,11 @@ declare namespace _default {
5
5
  files: {
6
6
  "agents/researcher.ts": string;
7
7
  "agents/writer.ts": string;
8
+ "app/api/workflows/[workflowId]/start/route.ts": string;
9
+ "app/api/workflows/runs/[id]/approvals/[approvalId]/route.ts": string;
10
+ "app/api/workflows/runs/[id]/route.ts": string;
11
+ "app/api/workflows/runs/route.ts": string;
12
+ "app/api/workflows/sample-runs.ts": string;
8
13
  "app/layout.tsx": string;
9
14
  "app/page.tsx": string;
10
15
  "app/workflows/[id]/page.tsx": string;
@@ -5,11 +5,16 @@ export default {
5
5
  "files": {
6
6
  "agents/researcher.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"researcher\",\n system:\n \"You research topics thoroughly and return structured findings. \" +\n \"Present results as clear bullet points with key facts, data, and sources.\",\n maxSteps: 3,\n});\n",
7
7
  "agents/writer.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"writer\",\n system:\n \"You transform research notes into polished, publication-ready content. \" +\n \"Use a professional but approachable tone.\",\n maxSteps: 3,\n});\n",
8
+ "app/api/workflows/[workflowId]/start/route.ts": "export async function POST(\n request: Request,\n context: { params: Record<string, string> },\n): Promise<Response> {\n const body = await request.json().catch(() => ({})) as {\n input?: { topic?: string };\n };\n const runId = `run-${Date.now()}`;\n\n return Response.json({\n success: true,\n runId,\n id: runId,\n workflowId: context.params.workflowId,\n status: \"pending\",\n input: body.input ?? {},\n createdAt: new Date().toISOString(),\n });\n}\n",
9
+ "app/api/workflows/runs/[id]/approvals/[approvalId]/route.ts": "export function POST(): Response {\n return Response.json({ success: true });\n}\n",
10
+ "app/api/workflows/runs/[id]/route.ts": "import { createDemoWorkflowRun } from \"../../sample-runs.ts\";\n\nexport function GET(\n _request: Request,\n context: { params: Record<string, string> },\n): Response {\n return Response.json(createDemoWorkflowRun(context.params.id));\n}\n",
11
+ "app/api/workflows/runs/route.ts": "import { createDemoWorkflowRun } from \"../sample-runs.ts\";\n\nexport function GET(request: Request): Response {\n const url = new URL(request.url);\n const workflowId = url.searchParams.get(\"workflowId\");\n const limit = Number(url.searchParams.get(\"limit\") ?? \"20\");\n\n const runs = [createDemoWorkflowRun()].filter((run) =>\n !workflowId || run.workflowId === workflowId\n ).slice(0, Number.isFinite(limit) ? limit : 20);\n\n return Response.json({\n runs,\n totalCount: runs.length,\n });\n}\n",
12
+ "app/api/workflows/sample-runs.ts": "export interface DemoWorkflowStep {\n id: string;\n name: string;\n status: \"pending\" | \"running\" | \"completed\" | \"waiting_for_approval\" | \"failed\";\n output?: string | Record<string, unknown>;\n}\n\nexport interface DemoWorkflowRun {\n id: string;\n workflowId: string;\n status: \"pending\" | \"running\" | \"completed\" | \"waiting_for_approval\" | \"failed\";\n input: { topic: string };\n createdAt: string;\n currentNodes: string[];\n nodeStates: Record<string, { status: DemoWorkflowStep[\"status\"] }>;\n pendingApprovals: Array<{ id: string; status: \"pending\" | \"approved\" | \"rejected\" }>;\n steps: DemoWorkflowStep[];\n}\n\nexport function createDemoWorkflowRun(\n id = \"test-run\",\n topic = \"Example content pipeline\",\n): DemoWorkflowRun {\n return {\n id,\n workflowId: \"content-pipeline\",\n status: \"completed\",\n input: { topic },\n createdAt: new Date().toISOString(),\n currentNodes: [],\n nodeStates: {\n research: { status: \"completed\" },\n \"write-article\": { status: \"completed\" },\n \"editorial-review\": { status: \"completed\" },\n publish: { status: \"completed\" },\n },\n pendingApprovals: [],\n steps: [\n {\n id: \"research\",\n name: \"Research\",\n status: \"completed\",\n output: \"Found key points and source material.\",\n },\n {\n id: \"write-article\",\n name: \"Write article\",\n status: \"completed\",\n output: \"Drafted a concise article from the research notes.\",\n },\n {\n id: \"editorial-review\",\n name: \"Editorial review\",\n status: \"completed\",\n },\n {\n id: \"publish\",\n name: \"Publish\",\n status: \"completed\",\n output: { published: true },\n },\n ],\n };\n}\n",
8
13
  "app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactNode {\n return (\n <>\n <Head>\n <title>AI Workflows</title>\n </Head>\n {children}\n </>\n );\n}\n",
9
14
  "app/page.tsx": "'use client'\n\nimport { useState } from 'react'\nimport { useWorkflowStart, useWorkflowList } from 'veryfront/workflow'\n\nconst STATUS_STYLES: Record<string, string> = {\n running: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n completed: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400',\n waiting_for_approval: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n failed: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n pending: 'bg-neutral-100 text-neutral-600 dark:bg-neutral-800 dark:text-neutral-400',\n}\n\nexport default function WorkflowDashboard(): JSX.Element {\n const [topic, setTopic] = useState('')\n const { start, isStarting } = useWorkflowStart({ workflowId: 'content-pipeline' })\n const { runs, isLoading } = useWorkflowList()\n\n async function handleStart(e: React.FormEvent) {\n e.preventDefault()\n if (!topic.trim()) return\n await start({ topic: topic.trim() })\n setTopic('')\n }\n\n return (\n <div className=\"min-h-screen bg-neutral-50 dark:bg-neutral-950\">\n <div className=\"max-w-2xl mx-auto px-4 py-12\">\n <div className=\"mb-10\">\n <h1 className=\"text-2xl font-bold text-neutral-900 dark:text-white\">Content Pipeline</h1>\n <p className=\"mt-1 text-neutral-500 dark:text-neutral-400\">Research &rarr; Write &rarr; Review &rarr; Publish</p>\n </div>\n\n {/* Start new workflow */}\n <form onSubmit={handleStart} className=\"mb-10\">\n <div className=\"flex gap-3\">\n <input\n type=\"text\"\n value={topic}\n onChange={(e) => setTopic(e.target.value)}\n placeholder=\"Enter a topic to research and write about...\"\n className=\"flex-1 px-4 py-2.5 bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-xl text-neutral-900 dark:text-white placeholder-neutral-400 focus:outline-none focus:ring-2 focus:ring-blue-500/30 focus:border-blue-500\"\n />\n <button\n type=\"submit\"\n disabled={isStarting || !topic.trim()}\n className=\"px-5 py-2.5 bg-blue-500 text-white font-medium rounded-xl hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {isStarting ? 'Starting...' : 'Start'}\n </button>\n </div>\n </form>\n\n {/* Workflow runs */}\n <div>\n <h2 className=\"text-sm font-medium text-neutral-500 dark:text-neutral-400 uppercase tracking-wider mb-4\">Recent Runs</h2>\n\n {isLoading ? (\n <p className=\"text-neutral-400 text-sm py-8 text-center\">Loading...</p>\n ) : runs.length === 0 ? (\n <div className=\"text-center py-12 bg-white dark:bg-neutral-900 rounded-2xl border border-neutral-200 dark:border-neutral-800\">\n <p className=\"text-neutral-500 dark:text-neutral-400\">No workflows yet. Start one above.</p>\n </div>\n ) : (\n <div className=\"space-y-3\">\n {runs.map((wf) => (\n <a\n key={wf.id}\n href={`/workflows/${wf.id}`}\n className=\"block bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-xl p-4 hover:border-neutral-300 dark:hover:border-neutral-700 transition-colors\"\n >\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"font-medium text-neutral-900 dark:text-white text-sm\">{wf.input?.topic || 'Untitled'}</p>\n <p className=\"text-xs text-neutral-500 mt-1\">{new Date(wf.createdAt).toLocaleString()}</p>\n </div>\n <span className={`px-2.5 py-1 rounded-full text-xs font-medium ${STATUS_STYLES[wf.status] || STATUS_STYLES.pending}`}>\n {wf.status.replace(/_/g, ' ')}\n </span>\n </div>\n </a>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n )\n}\n",
10
15
  "app/workflows/[id]/page.tsx": "'use client'\n\nimport { useState } from 'react'\nimport { usePageContext } from 'veryfront/context'\nimport { useWorkflow } from 'veryfront/workflow'\n\nconst STEP_ICONS: Record<string, string> = {\n completed: '\\u2713',\n running: '\\u25C9',\n pending: '\\u25CB',\n waiting_for_approval: '\\u23F8',\n failed: '\\u2717',\n}\n\nexport default function WorkflowDetail(): JSX.Element {\n const { params } = usePageContext()\n const { run, pendingApprovals, isLoading, refresh } = useWorkflow({ runId: params.id })\n const [isSubmitting, setIsSubmitting] = useState(false)\n\n async function handleApproval(approvalId: string, approved: boolean) {\n setIsSubmitting(true)\n try {\n await fetch(`/api/workflows/runs/${params.id}/approvals/${approvalId}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ approved, approver: 'user' }),\n })\n await refresh()\n } finally {\n setIsSubmitting(false)\n }\n }\n\n if (isLoading) {\n return (\n <div className=\"min-h-screen flex items-center justify-center bg-neutral-50 dark:bg-neutral-950\">\n <p className=\"text-neutral-400\">Loading workflow...</p>\n </div>\n )\n }\n\n if (!run) {\n return (\n <div className=\"min-h-screen flex items-center justify-center bg-neutral-50 dark:bg-neutral-950\">\n <p className=\"text-neutral-400\">Workflow not found</p>\n </div>\n )\n }\n\n return (\n <div className=\"min-h-screen bg-neutral-50 dark:bg-neutral-950\">\n <div className=\"max-w-2xl mx-auto px-4 py-12\">\n <a href=\"/\" className=\"text-sm text-neutral-500 hover:text-neutral-700 dark:hover:text-neutral-300 mb-6 inline-block\">&larr; Back</a>\n\n <h1 className=\"text-2xl font-bold text-neutral-900 dark:text-white mb-1\">{run.input?.topic || 'Workflow'}</h1>\n <p className=\"text-sm text-neutral-500 dark:text-neutral-400 mb-8\">Started {new Date(run.createdAt).toLocaleString()}</p>\n\n {/* Steps */}\n <div className=\"space-y-4 mb-8\">\n {run.steps?.map((step: any) => (\n <div key={step.id} className=\"flex items-start gap-3 bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-xl p-4\">\n <span className=\"text-lg mt-0.5\">{STEP_ICONS[step.status] || '\\u25CB'}</span>\n <div className=\"flex-1\">\n <p className=\"font-medium text-neutral-900 dark:text-white text-sm\">{step.name}</p>\n {step.output && (\n <p className=\"text-xs text-neutral-500 mt-1 line-clamp-2\">{typeof step.output === 'string' ? step.output : JSON.stringify(step.output)}</p>\n )}\n </div>\n <span className=\"text-xs text-neutral-400\">{step.status}</span>\n </div>\n ))}\n </div>\n\n {/* Approval */}\n {pendingApprovals.length > 0 && (\n <div className=\"bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-xl p-6\">\n <h2 className=\"font-medium text-amber-900 dark:text-amber-200 mb-2\">Approval Required</h2>\n <p className=\"text-sm text-amber-700 dark:text-amber-300 mb-4\">Review the draft before publishing.</p>\n <div className=\"flex gap-3\">\n <button\n onClick={() => handleApproval(pendingApprovals[0].id, true)}\n disabled={isSubmitting}\n className=\"px-4 py-2 bg-emerald-500 text-white font-medium rounded-lg hover:bg-emerald-600 disabled:opacity-50 transition-colors text-sm\"\n >\n Approve\n </button>\n <button\n onClick={() => handleApproval(pendingApprovals[0].id, false)}\n disabled={isSubmitting}\n className=\"px-4 py-2 bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 text-neutral-700 dark:text-neutral-300 font-medium rounded-lg hover:bg-neutral-50 dark:hover:bg-neutral-700 disabled:opacity-50 transition-colors text-sm\"\n >\n Reject\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n}\n",
11
16
  "globals.css": "@import \"tailwindcss\";\n",
12
- "README.md": "# Agentic Workflow\n\nOrchestrated multi-step processes with human approval gates.\n\n## What's included\n\n- Content pipeline workflow (research, write, review, publish)\n- Parallel step execution\n- Human-in-the-loop approval gates\n- Dashboard to start, monitor, and approve workflow runs\n\n## Structure\n\n```\nagents/\n researcher.ts Research agent\n writer.ts Writing agent\nworkflows/content-pipeline.ts Workflow definition\napp/\n page.tsx Workflow dashboard\n workflows/[id]/page.tsx Run detail and approval UI\n```\n\nThis starter is not production-ready.\n",
17
+ "README.md": "# Agentic Workflow\n\nOrchestrated multi-step processes with human approval gates.\n\n## What's included\n\n- Content pipeline workflow (research, write, review, publish)\n- Parallel step execution\n- Human-in-the-loop approval gates\n- Dashboard to start, monitor, and approve workflow runs\n\n## Structure\n\n```\nagents/\n researcher.ts Research agent\n writer.ts Writing agent\nworkflows/content-pipeline.ts Workflow definition\napp/\n api/workflows/ Demo workflow API routes\n page.tsx Workflow dashboard\n workflows/[id]/page.tsx Run detail and approval UI\n```\n\nThis starter is not production-ready.\n",
13
18
  "tsconfig.json": "{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"jsx\": \"react-jsx\",\n \"skipLibCheck\": true,\n \"esModuleInterop\": true,\n \"paths\": {\n \"@/*\": [\"./*\"]\n }\n },\n \"include\": [\"**/*.ts\", \"**/*.tsx\"],\n \"exclude\": [\"node_modules\"]\n}\n",
14
19
  "workflows/content-pipeline.ts": "import { workflow, step, parallel, waitForApproval } from \"veryfront/workflow\";\n\nexport default workflow({\n id: \"content-pipeline\",\n description: \"Research, write, review, and publish content\",\n steps: ({ input }) => [\n step(\"research\", {\n agent: \"researcher\",\n input: { topic: input.topic },\n }),\n\n parallel(\"draft\", [\n step(\"write-article\", { agent: \"writer\" }),\n step(\"write-summary\", { agent: \"writer\", input: { format: \"summary\" } }),\n ]),\n\n waitForApproval(\"editorial-review\", {\n message: \"Review the draft before publishing\",\n timeout: \"24h\",\n }),\n\n step(\"publish\", {\n execute: async ({ previous }) => {\n // Replace with your publishing logic\n return { published: true, url: `/articles/${Date.now()}` };\n },\n }),\n ],\n});\n"
15
20
  }
package/esm/deno.d.ts CHANGED
@@ -335,6 +335,7 @@ declare namespace _default {
335
335
  "test:e2e:rsc-browser": string;
336
336
  "test:e2e:binary": string;
337
337
  "test:e2e:binary:fresh": string;
338
+ "test:e2e:templates": string;
338
339
  "check:circular": string;
339
340
  cli: string;
340
341
  mcp: string;
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.610",
3
+ "version": "0.1.612",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "workspace": [
@@ -369,6 +369,7 @@ export default {
369
369
  "test:e2e:rsc-browser": "deno task generate && VF_DISABLE_LRU_INTERVAL=1 SSR_TRANSFORM_PER_PROJECT_LIMIT=0 REVALIDATION_PER_PROJECT_LIMIT=0 NODE_ENV=production LOG_FORMAT=text deno test --no-check --allow-all tests/e2e/regressions/rsc-proxy-hydration.test.ts --unstable-worker-options --unstable-net",
370
370
  "test:e2e:binary": "deno task generate && deno test --allow-all tests/integration/compiled-binary-e2e.test.ts",
371
371
  "test:e2e:binary:fresh": "deno task generate && VERYFRONT_BINARY_FRESH=1 deno test --allow-all tests/integration/compiled-binary-e2e.test.ts",
372
+ "test:e2e:templates": "deno run --allow-all scripts/test/template-runtime-e2e.ts",
372
373
  "check:circular": "deno run --allow-run --allow-read --allow-net scripts/lint/check-circular-baseline.ts",
373
374
  "cli": "deno run --allow-all cli/main.ts",
374
375
  "mcp": "deno run --allow-all cli/main.ts mcp",
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-sandbox-shell-tools/src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAE/B,MAAM,0CAA0C,CAAC;AAElD,KAAK,eAAe,GAAG,CACrB,KAAK,EAAE,4BAA4B,KAChC,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAAC;AAEjD,wBAAgB,+BAA+B,CAC7C,kBAAkB,EAAE,eAAe,GAClC,yBAAyB,CAE3B;AAED,QAAA,MAAM,QAAQ,2BAEZ,CAAC;AAEH,QAAA,MAAM,oBAAoB,EAAE,gBAa1B,CAAC;AAEH,eAAe,oBAAoB,CAAC;AACpC,OAAO,EAAE,QAAQ,IAAI,mCAAmC,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-sandbox-shell-tools/src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAE/B,MAAM,0CAA0C,CAAC;AAElD,KAAK,eAAe,GAAG,CACrB,KAAK,EAAE,4BAA4B,KAChC,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAAC;AAEjD,wBAAgB,+BAA+B,CAC7C,kBAAkB,EAAE,eAAe,GAClC,yBAAyB,CAE3B;AAED,QAAA,MAAM,QAAQ,2BAGZ,CAAC;AAEH,QAAA,MAAM,oBAAoB,EAAE,gBAa1B,CAAC;AAEH,eAAe,oBAAoB,CAAC;AACpC,OAAO,EAAE,QAAQ,IAAI,mCAAmC,EAAE,CAAC"}
@@ -3,12 +3,12 @@
3
3
  *
4
4
  * @module extensions/ext-sandbox-shell-tools
5
5
  */
6
- import { createBashTool as createBashToolImpl } from "bash-tool";
7
6
  import { SandboxShellToolsProviderName, } from "../../../src/extensions/sandbox/index.js";
8
7
  export function createSandboxShellToolsProvider(createBashToolImpl) {
9
8
  return async (input) => await createBashToolImpl(input);
10
9
  }
11
10
  const provider = createSandboxShellToolsProvider(async (input) => {
11
+ const { createBashTool: createBashToolImpl } = await import("bash-tool");
12
12
  return await createBashToolImpl(input);
13
13
  });
14
14
  const extSandboxShellTools = () => ({
@@ -1 +1 @@
1
- {"version":3,"file":"message-prep.d.ts","sourceRoot":"","sources":["../../../src/src/chat/message-prep.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC;AAQjC,OAAO,EAKL,KAAK,aAAa,EAGlB,KAAK,oBAAoB,EAE1B,MAAM,YAAY,CAAC;AAIpB,uBAAuB;AACvB,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAErD;AAOD,qBAAqB;AACrB,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,oBAAoB,EAAE,EAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,oBAAoB,EAAE,CAiCxB;AAqCD,kDAAkD;AAClD,wBAAgB,qCAAqC,CACnD,QAAQ,EAAE,oBAAoB,EAAE,EAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,oBAAoB,EAAE,CAiExB;AA+BD,4DAA4D;AAC5D,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAGxE;AAED,gDAAgD;AAChD,wBAAgB,kCAAkC,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAwB7F;AAED,qDAAqD;AACrD,wBAAgB,wCAAwC,CACtD,QAAQ,EAAE,aAAa,EAAE,GACxB,aAAa,EAAE,CAmDjB;AAyCD,gCAAgC;AAChC,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAiBhF;AAsFD,wCAAwC;AACxC,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,oBAAoB,EAAE,GAC/B,oBAAoB,EAAE,CAwBxB;AAED;;GAEG;AACH,4CAA4C;AAC5C,eAAO,MAAM,qBAAqB,sCAAgC,CAAC;AAYnE,wDAAwD;AACxD,wBAAgB,0CAA0C,CACxD,QAAQ,EAAE,aAAa,EAAE,GACxB,oBAAoB,EAAE,CAiBxB;AA4FD,6BAA6B;AAC7B,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CAsE3F;AAWD,yBAAyB;AACzB,wBAAgB,eAAe,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CA4IxF;AAED,yBAAyB;AACzB,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGjF;AAED,sCAAsC;AACtC,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CA4B7F;AAED,wBAAwB;AACxB,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,oBAAoB,EAAE,EAChC,QAAQ,GAAE,MAAU,GACnB,oBAAoB,EAAE,CAexB;AAED,2BAA2B;AAC3B,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CA0D1F;AAED,4BAA4B;AAC5B,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,oBAAoB,EAAE,EAChC,MAAM,GAAE,MAA6B,EACrC,QAAQ,GAAE,MAAU,GACnB,oBAAoB,EAAE,CAMxB;AAED;;GAEG;AACH,4DAA4D;AAC5D,eAAO,MAAM,kCAAkC,mDAA6C,CAAC"}
1
+ {"version":3,"file":"message-prep.d.ts","sourceRoot":"","sources":["../../../src/src/chat/message-prep.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC;AAQjC,OAAO,EAKL,KAAK,aAAa,EAGlB,KAAK,oBAAoB,EAE1B,MAAM,YAAY,CAAC;AAMpB,uBAAuB;AACvB,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAErD;AAOD,qBAAqB;AACrB,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,oBAAoB,EAAE,EAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,oBAAoB,EAAE,CAiCxB;AAqCD,kDAAkD;AAClD,wBAAgB,qCAAqC,CACnD,QAAQ,EAAE,oBAAoB,EAAE,EAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,oBAAoB,EAAE,CAiExB;AA+BD,4DAA4D;AAC5D,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAGxE;AAED,gDAAgD;AAChD,wBAAgB,kCAAkC,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAwB7F;AAED,qDAAqD;AACrD,wBAAgB,wCAAwC,CACtD,QAAQ,EAAE,aAAa,EAAE,GACxB,aAAa,EAAE,CAmDjB;AAyCD,gCAAgC;AAChC,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAiBhF;AAsFD,wCAAwC;AACxC,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,oBAAoB,EAAE,GAC/B,oBAAoB,EAAE,CAwBxB;AAED;;GAEG;AACH,4CAA4C;AAC5C,eAAO,MAAM,qBAAqB,sCAAgC,CAAC;AAYnE,wDAAwD;AACxD,wBAAgB,0CAA0C,CACxD,QAAQ,EAAE,aAAa,EAAE,GACxB,oBAAoB,EAAE,CAiBxB;AA4ND,6BAA6B;AAC7B,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CA4E3F;AAWD,yBAAyB;AACzB,wBAAgB,eAAe,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CA4IxF;AAED,yBAAyB;AACzB,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGjF;AAED,sCAAsC;AACtC,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CA4B7F;AAED,wBAAwB;AACxB,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,oBAAoB,EAAE,EAChC,QAAQ,GAAE,MAAU,GACnB,oBAAoB,EAAE,CAexB;AAED,2BAA2B;AAC3B,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CA0D1F;AAED,4BAA4B;AAC5B,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,oBAAoB,EAAE,EAChC,MAAM,GAAE,MAA6B,EACrC,QAAQ,GAAE,MAAU,GACnB,oBAAoB,EAAE,CAMxB;AAED;;GAEG;AACH,4DAA4D;AAC5D,eAAO,MAAM,kCAAkC,mDAA6C,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { convertUiMessagesToProviderModelMessages, getStringField, isReasoningPart, isToolCallPart, isToolResultPart, } from "./conversation.js";
2
2
  import { buildDataFileAnnotation, normalizeInlineAttachmentMediaType, } from "./types.js";
3
+ import { historicalToolSummaries } from "../integrations/_tool_summaries.js";
3
4
  const CHARS_PER_TOKEN = 4;
4
5
  /** Estimate tokens. */
5
6
  export function estimateTokens(value) {
@@ -467,6 +468,106 @@ function maskTask(output, charCount) {
467
468
  function maskGeneric(toolName, charCount) {
468
469
  return `[${toolName} output omitted (${charCount} chars)]`;
469
470
  }
471
+ function compactContactValue(value) {
472
+ if (typeof value === "string")
473
+ return value;
474
+ if (!isRecord(value))
475
+ return null;
476
+ const compact = {};
477
+ const emailAddress = value.emailAddress;
478
+ if (isRecord(emailAddress)) {
479
+ if (typeof emailAddress.name === "string")
480
+ compact.name = emailAddress.name;
481
+ if (typeof emailAddress.address === "string")
482
+ compact.address = emailAddress.address;
483
+ }
484
+ for (const field of ["name", "address", "email"]) {
485
+ if (typeof value[field] === "string")
486
+ compact[field] = value[field];
487
+ }
488
+ return Object.keys(compact).length > 0 ? compact : null;
489
+ }
490
+ function compactHistoricalField(field, fieldValue) {
491
+ if (field.kind === "contact") {
492
+ return compactContactValue(fieldValue);
493
+ }
494
+ if (field.kind === "contact-array") {
495
+ if (!Array.isArray(fieldValue))
496
+ return null;
497
+ const contacts = fieldValue
498
+ .map((item) => compactContactValue(item))
499
+ .filter((item) => item !== null);
500
+ return contacts.length > 0 ? contacts : null;
501
+ }
502
+ if (field.kind === "string-array") {
503
+ if (!Array.isArray(fieldValue))
504
+ return null;
505
+ const strings = fieldValue.filter((item) => typeof item === "string");
506
+ return strings.length > 0 ? strings : null;
507
+ }
508
+ if (typeof fieldValue === "string") {
509
+ return field.maxLength ? truncate(fieldValue, field.maxLength) : fieldValue;
510
+ }
511
+ if (typeof fieldValue === "boolean" || typeof fieldValue === "number") {
512
+ return fieldValue;
513
+ }
514
+ if (Array.isArray(fieldValue)) {
515
+ const strings = fieldValue.filter((item) => typeof item === "string");
516
+ return strings.length > 0 ? strings : null;
517
+ }
518
+ return null;
519
+ }
520
+ function compactHistoricalItemValue(value, fields) {
521
+ if (!isRecord(value))
522
+ return null;
523
+ const compact = {};
524
+ for (const field of fields) {
525
+ const fieldValue = compactHistoricalField(field, value[field.name]);
526
+ if (fieldValue !== null)
527
+ compact[field.name] = fieldValue;
528
+ }
529
+ return Object.keys(compact).length > 0 ? compact : null;
530
+ }
531
+ function findHistoricalToolSummaryContract(toolName) {
532
+ return historicalToolSummaries[toolName] ?? null;
533
+ }
534
+ function getHistoricalSummaryItems(parsed, contract) {
535
+ if (Array.isArray(parsed))
536
+ return parsed;
537
+ if (!isRecord(parsed))
538
+ return null;
539
+ for (const key of contract.collectionKeys) {
540
+ const value = parsed[key];
541
+ if (Array.isArray(value))
542
+ return value;
543
+ }
544
+ return null;
545
+ }
546
+ function compactHistoricalToolSummaryOutput(rawValue, contract) {
547
+ const parsed = tryParseJson(rawValue);
548
+ const output = isRecord(parsed) ? parsed : null;
549
+ const sourceItems = getHistoricalSummaryItems(parsed, contract);
550
+ if (!sourceItems)
551
+ return null;
552
+ const items = sourceItems
553
+ .map((item) => compactHistoricalItemValue(item, contract.itemFields))
554
+ .filter((item) => item !== null);
555
+ if (items.length === 0)
556
+ return null;
557
+ const compacted = {
558
+ [`${contract.collectionName}Count`]: items.length,
559
+ [contract.collectionName]: items,
560
+ omitted: contract.omitted,
561
+ };
562
+ if (output && contract.outputFields) {
563
+ for (const field of contract.outputFields) {
564
+ const fieldValue = compactHistoricalField(field, output[field.name]);
565
+ if (fieldValue !== null)
566
+ compacted[field.name] = fieldValue;
567
+ }
568
+ }
569
+ return compacted;
570
+ }
470
571
  function getOutputValue(output) {
471
572
  if (!isRecord(output))
472
573
  return output;
@@ -522,26 +623,33 @@ export function maskOldToolOutputs(messages) {
522
623
  const toolName = part.toolName || callInfo?.toolName || "unknown";
523
624
  const input = callInfo?.input;
524
625
  let masked;
525
- switch (toolName) {
526
- case "readFile":
527
- case "get_file":
528
- masked = maskReadFile(input, charCount);
529
- break;
530
- case "bash":
531
- masked = maskBash(input, rawValue, charCount);
532
- break;
533
- case "web_search":
534
- masked = maskWebSearch(rawValue);
535
- break;
536
- case "web_fetch":
537
- masked = maskWebFetch(input, charCount);
538
- break;
539
- case "task":
540
- masked = maskTask(rawValue, charCount);
541
- break;
542
- default:
543
- masked = maskGeneric(toolName, charCount);
544
- break;
626
+ const summaryContract = findHistoricalToolSummaryContract(toolName);
627
+ if (summaryContract) {
628
+ masked = compactHistoricalToolSummaryOutput(rawValue, summaryContract) ??
629
+ maskGeneric(toolName, charCount);
630
+ }
631
+ else {
632
+ switch (toolName) {
633
+ case "readFile":
634
+ case "get_file":
635
+ masked = maskReadFile(input, charCount);
636
+ break;
637
+ case "bash":
638
+ masked = maskBash(input, rawValue, charCount);
639
+ break;
640
+ case "web_search":
641
+ masked = maskWebSearch(rawValue);
642
+ break;
643
+ case "web_fetch":
644
+ masked = maskWebFetch(input, charCount);
645
+ break;
646
+ case "task":
647
+ masked = maskTask(rawValue, charCount);
648
+ break;
649
+ default:
650
+ masked = maskGeneric(toolName, charCount);
651
+ break;
652
+ }
545
653
  }
546
654
  return { ...part, output: wrapToolResultOutput(part.output, masked) };
547
655
  });
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-loader.d.ts","sourceRoot":"","sources":["../../../../src/src/html/styles-builder/plugin-loader.ts"],"names":[],"mappings":"AAqHA;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA4D/E;AAED,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAC/B,OAAO,CAAC,OAAO,CAAC,CAwClB"}
1
+ {"version":3,"file":"plugin-loader.d.ts","sourceRoot":"","sources":["../../../../src/src/html/styles-builder/plugin-loader.ts"],"names":[],"mappings":"AAgIA;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA4D/E;AAED,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAC/B,OAAO,CAAC,OAAO,CAAC,CAwClB"}
@@ -55,7 +55,14 @@ catch {
55
55
  // by the `@veryfront/ext-css-tailwind` extension's `setup()` hook — they depend on
56
56
  // tailwindcss imports that live in the extension package, not in core.
57
57
  function isRealDenoRuntime() {
58
- return typeof dntShim.Deno !== "undefined" && typeof dntShim.Deno.version === "object";
58
+ const global = dntShim.dntGlobalThis;
59
+ const isNodeLike = global.process?.versions?.node != null && !global.process?.versions?.deno;
60
+ return !global.Bun &&
61
+ !isNodeLike &&
62
+ typeof dntShim.Deno !== "undefined" &&
63
+ typeof dntShim.Deno.version === "object" &&
64
+ typeof dntShim.Deno.build === "object" &&
65
+ typeof dntShim.Deno.build.os === "string";
59
66
  }
60
67
  function encodeToBase64(source) {
61
68
  const bufferCtor = dntShim.dntGlobalThis.Buffer;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/src/html/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAc1D,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAQR;AAiND,UAAU,qBAAqB;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAWD,wBAAsB,kBAAkB,CACtC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACvD,OAAO,CAAC,MAAM,CAAC,CA+DjB;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAElF"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/src/html/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAc1D,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAQR;AAmND,UAAU,qBAAqB;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAWD,wBAAsB,kBAAkB,CACtC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACvD,OAAO,CAAC,MAAM,CAAC,CA+DjB;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAElF"}
@@ -33,6 +33,7 @@ const PLATFORM_UTILITY_PATHS = {
33
33
  chat: "/_vf_modules/_veryfront/chat/index.js",
34
34
  markdown: "/_vf_modules/_veryfront/markdown/index.js",
35
35
  mdx: "/_vf_modules/_veryfront/mdx/index.js",
36
+ workflow: "/_vf_modules/_veryfront/workflow/react/index.js",
36
37
  };
37
38
  // Core platform utilities that are always served locally (embedded in compiled binary)
38
39
  const CORE_PLATFORM_UTILITIES = {
@@ -50,6 +51,7 @@ const AI_MODULE_UTILITIES = {
50
51
  "veryfront/chat": PLATFORM_UTILITY_PATHS.chat,
51
52
  "veryfront/markdown": PLATFORM_UTILITY_PATHS.markdown,
52
53
  "veryfront/mdx": PLATFORM_UTILITY_PATHS.mdx,
54
+ "veryfront/workflow": PLATFORM_UTILITY_PATHS.workflow,
53
55
  };
54
56
  const PLATFORM_UTILITIES = {
55
57
  ...CORE_PLATFORM_UTILITIES,