wizards 0.2.16 → 0.2.18
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/apps/runtime/dist/agents/project-assistant.js +20 -2
- package/apps/runtime/dist/authoring/guide.js +6 -3
- package/apps/runtime/dist/credits/estimate.js +14 -8
- package/apps/runtime/dist/db/migrations/tenant/0008_run_event_note.sql +1 -0
- package/apps/runtime/dist/db/migrations/tenant/0009_knowledge.sql +104 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0008_snapshot.json +2019 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0009_snapshot.json +2837 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +14 -0
- package/apps/runtime/dist/db/schema.js +162 -8
- package/apps/runtime/dist/engine/events.js +14 -2
- package/apps/runtime/dist/engine/prepare.js +5 -2
- package/apps/runtime/dist/engine/requirements.js +108 -0
- package/apps/runtime/dist/engine/runner.js +2 -2
- package/apps/runtime/dist/engine/steps.js +21 -21
- package/apps/runtime/dist/engine/template.js +13 -10
- package/apps/runtime/dist/env.js +2 -0
- package/apps/runtime/dist/files/storage.js +15 -0
- package/apps/runtime/dist/models.js +38 -0
- package/apps/runtime/dist/plugins/loader.js +2 -0
- package/apps/runtime/dist/routes/studio.js +149 -8
- package/apps/runtime/dist/services/cloud.js +59 -1
- package/apps/runtime/dist/services/knowledge-model.js +558 -0
- package/apps/runtime/dist/services/knowledge.js +721 -0
- package/apps/runtime/dist/services/marketplace.js +2 -2
- package/apps/runtime/dist/services/project-files.js +114 -6
- package/apps/runtime/dist/services/project-index.js +632 -94
- package/apps/runtime/dist/services/relevance.js +90 -0
- package/apps/runtime/dist/services/space-categories.js +882 -0
- package/apps/runtime/dist/services/space-data.js +466 -38
- package/apps/runtime/dist/services/space-origin.js +164 -0
- package/apps/runtime/dist/services/spaces.js +155 -1
- package/apps/runtime/dist/tools/browser.js +12 -6
- package/apps/runtime/dist/tools/index.js +12 -6
- package/apps/runtime/dist/tools/mail.js +5 -2
- package/apps/runtime/dist/tools/pages.js +28 -23
- package/apps/runtime/dist/tools/project.js +132 -39
- package/apps/runtime/dist/tools/store.js +4 -4
- package/apps/runtime/dist/widgets/step.js +10 -4
- package/apps/web/dist/assets/{Account-BE_W101C.js → Account-Cp1cgqjV.js} +1 -1
- package/apps/web/dist/assets/{ChangelogDialog-DjKQJAos.js → ChangelogDialog-Chke1qUe.js} +1 -1
- package/apps/web/dist/assets/ChatPanel-DWrwewr6.js +1 -0
- package/apps/web/dist/assets/CreditsDialog-Ckema8Ss.js +1 -0
- package/apps/web/dist/assets/EditorPage-XX6pfHk5.js +2 -0
- package/apps/web/dist/assets/{FlowPreview-DK4RZqTW.js → FlowPreview-DS545n78.js} +1 -1
- package/apps/web/dist/assets/{Harness-DcI94f1U.js → Harness-H3yXP-2L.js} +2 -2
- package/apps/web/dist/assets/{HomePage-BBNFgryu.js → HomePage-Bds84ShK.js} +1 -1
- package/apps/web/dist/assets/{ImportWizard-BoYqovdl.js → ImportWizard-0_NkA8aS.js} +1 -1
- package/apps/web/dist/assets/LocalRuntime-DnABzTOe.js +1 -0
- package/apps/web/dist/assets/{NewWizardPage-tKV2S4eK.js → NewWizardPage-BqP75V9K.js} +2 -2
- package/apps/web/dist/assets/ProjectPage-DbOvwOdZ.js +5 -0
- package/apps/web/dist/assets/PublicRunner-CtZ7vxl_.js +1 -0
- package/apps/web/dist/assets/RunnerView-xV5bWclu.js +70 -0
- package/apps/web/dist/assets/SettingsPage-DKt55zFh.js +1 -0
- package/apps/web/dist/assets/{SetupPage-qxHvlf87.js → SetupPage-c6mMD9zN.js} +1 -1
- package/apps/web/dist/assets/SharePage-DTKIbMj-.js +1 -0
- package/apps/web/dist/assets/{api-t9_w1XNe.js → api-CVG-xDEn.js} +2 -2
- package/apps/web/dist/assets/changelog-CXXT0zsp.js +1 -0
- package/apps/web/dist/assets/{esm-D0YVMTdo.js → esm-DLM3jdbm.js} +1 -1
- package/apps/web/dist/assets/index-1gmaxDSk.js +10 -0
- package/apps/web/dist/assets/index-Bwyehu0k.css +1 -0
- package/apps/web/dist/assets/{meta-BJHYbMh7.js → meta-m947x6uG.js} +1 -1
- package/apps/web/dist/assets/{settings-menu-BqqUAvIY.js → settings-menu-DUY6__C3.js} +1 -1
- package/apps/web/dist/assets/ui-BPY2pIh0.js +1 -0
- package/apps/web/dist/index.html +4 -4
- package/apps/web/dist/mcp/flow.html +54 -54
- package/node_modules/@engenty-wizards/plugin-sdk/dist/index.d.ts +164 -0
- package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +10 -0
- package/node_modules/@engenty-wizards/shared/dist/definition.js +25 -0
- package/node_modules/@engenty-wizards/shared/dist/knowledge.d.ts +199 -0
- package/node_modules/@engenty-wizards/shared/dist/knowledge.js +68 -0
- package/node_modules/@engenty-wizards/shared/dist/projects.d.ts +1 -16
- package/node_modules/@engenty-wizards/shared/dist/projects.js +1 -1
- package/node_modules/@engenty-wizards/shared/dist/run.d.ts +149 -0
- package/node_modules/@engenty-wizards/shared/dist/run.js +77 -1
- package/node_modules/@engenty-wizards/shared/dist/space-data.d.ts +20 -0
- package/node_modules/@engenty-wizards/shared/dist/space-data.js +2 -1
- package/package.json +1 -1
- package/apps/web/dist/assets/ChatPanel-BWrcDs4s.js +0 -1
- package/apps/web/dist/assets/CreditsDialog-DUjR5xkl.js +0 -1
- package/apps/web/dist/assets/EditorPage-CrOqikP2.js +0 -2
- package/apps/web/dist/assets/LocalRuntime-BD8zGN8w.js +0 -1
- package/apps/web/dist/assets/ProjectPage-voR0hvzy.js +0 -4
- package/apps/web/dist/assets/PublicRunner-CYZE_hSi.js +0 -1
- package/apps/web/dist/assets/RunnerView-D_C7hn81.js +0 -70
- package/apps/web/dist/assets/SettingsPage-DguoPF_3.js +0 -1
- package/apps/web/dist/assets/SharePage-Cf3i7KB-.js +0 -1
- package/apps/web/dist/assets/changelog-kz0DmHY4.js +0 -1
- package/apps/web/dist/assets/index-BPpKz65x.css +0 -1
- package/apps/web/dist/assets/index-D5w3fW1p.js +0 -10
- package/apps/web/dist/assets/ui-BHXO_e0e.js +0 -1
|
@@ -600,6 +600,44 @@ export async function embeddingModel() {
|
|
|
600
600
|
? { model: gatewayClient(access, {}).embeddingModel("wizards/embedding"), ref: bound.model }
|
|
601
601
|
: null;
|
|
602
602
|
}
|
|
603
|
+
/**
|
|
604
|
+
* The way to TypeSafe's Jev, a classifier that answers typed questions with probabilities and
|
|
605
|
+
* writes no text: the credits on a Manage-App's runtime; alone, an AI Gateway key, a TypeSafe
|
|
606
|
+
* key, or the linked account's credits. Null when there is none.
|
|
607
|
+
*/
|
|
608
|
+
export async function systemOneAccess() {
|
|
609
|
+
const cfg = await config();
|
|
610
|
+
const viaCredits = (access) => ({
|
|
611
|
+
url: `${access.baseUrl}/v4/ai/systemone`,
|
|
612
|
+
headers: {
|
|
613
|
+
authorization: `Bearer ${access.token}`,
|
|
614
|
+
// Booked under the classifier class; its evaluation model answers.
|
|
615
|
+
"ai-model-id": "wizards/classifier",
|
|
616
|
+
...(access.tenant ? { "x-wizards-tenant": access.tenant } : {}),
|
|
617
|
+
},
|
|
618
|
+
model: null,
|
|
619
|
+
});
|
|
620
|
+
if (managed) {
|
|
621
|
+
const access = await creditAccess(cfg, true).catch(() => null);
|
|
622
|
+
return access ? viaCredits(access) : null;
|
|
623
|
+
}
|
|
624
|
+
if (cfg.keys.gateway) {
|
|
625
|
+
return {
|
|
626
|
+
url: "https://ai-gateway.vercel.sh/typesafe/v1/systemone",
|
|
627
|
+
headers: { authorization: `Bearer ${cfg.keys.gateway}` },
|
|
628
|
+
model: "typesafe-ai/jev",
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
if (env.typesafeKey) {
|
|
632
|
+
return {
|
|
633
|
+
url: "https://api.typesafe.ai/v1/systemone",
|
|
634
|
+
headers: { authorization: `Bearer ${env.typesafeKey}` },
|
|
635
|
+
model: "jev-latest",
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
const access = await creditAccess(cfg, false).catch(() => null);
|
|
639
|
+
return access ? viaCredits(access) : null;
|
|
640
|
+
}
|
|
603
641
|
/** Search tools an AI Gateway runs itself; they travel in the request, so any gateway client names them. */
|
|
604
642
|
export const gatewayTools = createGateway({ apiKey: "unused" }).tools;
|
|
605
643
|
/**
|
|
@@ -11,6 +11,7 @@ import { parseDocument } from "../documents/parse.js";
|
|
|
11
11
|
import { env } from "../env.js";
|
|
12
12
|
import { ModelUnavailableError, textModel } from "../models.js";
|
|
13
13
|
import { putIndexEntry, removeIndexEntries } from "../services/project-index.js";
|
|
14
|
+
import { originData } from "../services/space-origin.js";
|
|
14
15
|
import { safeFetch } from "../tools/net-guard.js";
|
|
15
16
|
import { discoverPlugins } from "./discovery.js";
|
|
16
17
|
import { migrateOpenTenants, migratePlugins } from "./migrations.js";
|
|
@@ -112,6 +113,7 @@ function apiFor(record) {
|
|
|
112
113
|
put: (entry) => putIndexEntry(source.id, entry),
|
|
113
114
|
remove: (space, key) => removeIndexEntries(source.id, space, key),
|
|
114
115
|
},
|
|
116
|
+
spaceData: originData(source.id),
|
|
115
117
|
web: {
|
|
116
118
|
fetch: (url, init) => safeFetch(url, init),
|
|
117
119
|
read: (url, options) => readPage(url, options?.signal),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mkdirSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { MODEL_CLASSES, TEXT_CLASSES } from "@engenty-wizards/shared/definition";
|
|
4
|
+
import { CATEGORY_TYPES, whereSchema } from "@engenty-wizards/shared/knowledge";
|
|
4
5
|
import { PROJECT_FILE_KINDS } from "@engenty-wizards/shared/projects";
|
|
5
6
|
import { isCreditsRef } from "@engenty-wizards/shared/providers";
|
|
6
7
|
import { generateText } from "ai";
|
|
@@ -16,7 +17,7 @@ import { layout } from "../cli/home.js";
|
|
|
16
17
|
import { connectorImportSchema, importConnector, listConnectors, previewSource, refreshConnector, registryService, removeConnector, searchRegistry, } from "../connectors/external.js";
|
|
17
18
|
import { balanceCredits, canSpend } from "../credits/credits.js";
|
|
18
19
|
import { estimateRun } from "../credits/estimate.js";
|
|
19
|
-
import { missingModels } from "../engine/requirements.js";
|
|
20
|
+
import { missingModels, stepsWithoutModel } from "../engine/requirements.js";
|
|
20
21
|
import { env } from "../env.js";
|
|
21
22
|
import { freshAuth, loginEnv } from "../harness/env.js";
|
|
22
23
|
import { detectHarness, detectHarnesses, HARNESS_IDS, harness, installSpec, } from "../harness/index.js";
|
|
@@ -30,15 +31,18 @@ import { HTML_RESPONSE_CSP } from "../render/guard.js";
|
|
|
30
31
|
import { mayBuild, projectWritable, requireWritable } from "../services/access.js";
|
|
31
32
|
import { architectTurn } from "../services/architect.js";
|
|
32
33
|
import { checkForCloud, cloudLinked, cloudSpaces, cloudState, forgetCloud, publishAndSync, pushSharing, removeFromCloud, replaceCloudSpaces, rotateInCloud, syncToCloud, } from "../services/cloud.js";
|
|
33
|
-
import { ServiceError } from "../services/errors.js";
|
|
34
|
+
import { notFound, ServiceError } from "../services/errors.js";
|
|
34
35
|
import { deleteFile, listFiles, readFile, writeFile } from "../services/files.js";
|
|
36
|
+
import { categoryContents, listKnowledge, resolvePath, valueContents, } from "../services/knowledge.js";
|
|
37
|
+
import { writeSummary } from "../services/knowledge-model.js";
|
|
35
38
|
import { exportWizard, importWizard, PACKAGE_EXTENSION, PACKAGE_MAX_BYTES, PACKAGE_MIME, } from "../services/package.js";
|
|
36
39
|
import { profileSchema, saveProfile, userProfile } from "../services/profile.js";
|
|
37
40
|
import { addProjectFile, fileView, orderProjectFiles, projectFile, projectFileContent, projectFiles, reindexProjectFile, removeProjectFile, updateProjectFile, } from "../services/project-files.js";
|
|
38
|
-
import { documentText,
|
|
41
|
+
import { documentText, queueIndex, searchKnowledge } from "../services/project-index.js";
|
|
39
42
|
import { createProject, deleteProject, listProjects, maskedServers, ownedProject, projectLimit, projectPatchSchema, updateProject, } from "../services/projects.js";
|
|
40
43
|
import { listResults, listRuns, startTestRun } from "../services/runs.js";
|
|
41
|
-
import {
|
|
44
|
+
import { addCategoryValue, categoryRow, categoryValue, deleteCategory, deleteCategoryValue, mergeCategoryValues, orderCategoryValues, putCategory, renameCategoryValue, setItemCategory, updateCategory, } from "../services/space-categories.js";
|
|
45
|
+
import { addTableRow, createPage, createTable, deletePage, deleteTable, deleteTableRows, getPage, getTable, listSpaceData, orderSubPages, updatePage, updateTable, updateTableRow, } from "../services/space-data.js";
|
|
42
46
|
import { draftWidgetPreview } from "../services/widgets.js";
|
|
43
47
|
import { createWizard, deleteWizard, duplicateWizard, listWizards, ownedWizard, rotateShareLink, updateWizardSettings, wizardMessages, wizardState, writableWizard, writeDraft, } from "../services/wizards.js";
|
|
44
48
|
import { readSetting, writeSetting } from "../settings.js";
|
|
@@ -344,11 +348,13 @@ export const studio = new Hono()
|
|
|
344
348
|
const text = await documentText(row);
|
|
345
349
|
return c.json({ text: text.slice(0, limit), chars: text.length });
|
|
346
350
|
})
|
|
347
|
-
// What
|
|
351
|
+
// What a search of Wissen finds for a question: the items an agent step would get.
|
|
348
352
|
.post("/projects/:id/search", async (c) => {
|
|
349
353
|
const project = await ownedProject(c.get("user").id, c.req.param("id"));
|
|
350
|
-
const
|
|
351
|
-
|
|
354
|
+
const body = z
|
|
355
|
+
.object({ query: z.string().min(1).max(400), where: whereSchema.optional() })
|
|
356
|
+
.parse(await c.req.json());
|
|
357
|
+
return c.json(await searchKnowledge(project.id, body.query, { where: body.where }));
|
|
352
358
|
})
|
|
353
359
|
// The assistant fills the project in: from a description, a website, the files given.
|
|
354
360
|
.post("/projects/:id/assist", async (c) => {
|
|
@@ -362,6 +368,7 @@ export const studio = new Hono()
|
|
|
362
368
|
.array(z.object({ role: z.enum(["user", "assistant"]), content: z.string().max(8000) }))
|
|
363
369
|
.max(24)
|
|
364
370
|
.default([]),
|
|
371
|
+
part: z.enum(["info", "knowledge"]).default("info"),
|
|
365
372
|
})
|
|
366
373
|
.parse(await c.req.json());
|
|
367
374
|
if (!(await canSpend())) {
|
|
@@ -376,6 +383,7 @@ export const studio = new Hono()
|
|
|
376
383
|
projectId: project.id,
|
|
377
384
|
message: body.message,
|
|
378
385
|
history: body.history,
|
|
386
|
+
part: body.part,
|
|
379
387
|
signal: abort.signal,
|
|
380
388
|
onText: (delta) => {
|
|
381
389
|
void stream.writeSSE({ event: "text", data: JSON.stringify(delta) });
|
|
@@ -466,6 +474,128 @@ export const studio = new Hono()
|
|
|
466
474
|
mode: query.mode,
|
|
467
475
|
days: query.days,
|
|
468
476
|
}));
|
|
477
|
+
})
|
|
478
|
+
// --- Wissen: its items and Kategorien ---------------------------------------
|
|
479
|
+
.get("/projects/:id/knowledge", async (c) => c.json(await listKnowledge(c.get("user").id, c.req.param("id"))))
|
|
480
|
+
// What a link in a page names (`pages/bgb/p-281`): the studio opens it.
|
|
481
|
+
.get("/projects/:id/resolve", async (c) => {
|
|
482
|
+
const project = await ownedProject(c.get("user").id, c.req.param("id"));
|
|
483
|
+
const found = await resolvePath(project.id, z.string().max(600).parse(c.req.query("path")));
|
|
484
|
+
if (!found) {
|
|
485
|
+
throw notFound();
|
|
486
|
+
}
|
|
487
|
+
return c.json(found);
|
|
488
|
+
})
|
|
489
|
+
.post("/projects/:id/categories", async (c) => {
|
|
490
|
+
const project = await ownedProject(c.get("user").id, c.req.param("id"));
|
|
491
|
+
await requireWritable(project);
|
|
492
|
+
const body = z
|
|
493
|
+
.object({
|
|
494
|
+
name: z.string().min(1).max(80),
|
|
495
|
+
type: z.enum(CATEGORY_TYPES),
|
|
496
|
+
unit: z.string().max(20).nullish(),
|
|
497
|
+
multiple: z.boolean().optional(),
|
|
498
|
+
ordered: z.boolean().optional(),
|
|
499
|
+
hint: z.string().max(120).nullish(),
|
|
500
|
+
values: z.array(z.string().max(200)).max(200).optional(),
|
|
501
|
+
tableId: z.string().nullish(),
|
|
502
|
+
columnId: z.string().nullish(),
|
|
503
|
+
})
|
|
504
|
+
.parse(await c.req.json());
|
|
505
|
+
const row = await putCategory(project.id, body);
|
|
506
|
+
return c.json({ id: row.id });
|
|
507
|
+
})
|
|
508
|
+
.patch("/categories/:id", async (c) => {
|
|
509
|
+
const row = await categoryRow(c.req.param("id"));
|
|
510
|
+
await ownedProject(c.get("user").id, row.projectId);
|
|
511
|
+
const body = z
|
|
512
|
+
.object({
|
|
513
|
+
name: z.string().min(1).max(80).optional(),
|
|
514
|
+
unit: z.string().max(20).nullish(),
|
|
515
|
+
multiple: z.boolean().optional(),
|
|
516
|
+
ordered: z.boolean().optional(),
|
|
517
|
+
hint: z.string().max(120).nullish(),
|
|
518
|
+
proposed: z.literal(false).optional(),
|
|
519
|
+
position: z.number().int().min(0).optional(),
|
|
520
|
+
})
|
|
521
|
+
.parse(await c.req.json());
|
|
522
|
+
await updateCategory(row.id, body);
|
|
523
|
+
return c.json({ ok: true });
|
|
524
|
+
})
|
|
525
|
+
.delete("/categories/:id", async (c) => {
|
|
526
|
+
const row = await categoryRow(c.req.param("id"));
|
|
527
|
+
await ownedProject(c.get("user").id, row.projectId);
|
|
528
|
+
await deleteCategory(row.id);
|
|
529
|
+
return c.json({ ok: true });
|
|
530
|
+
})
|
|
531
|
+
.post("/categories/:id/values", async (c) => {
|
|
532
|
+
const row = await categoryRow(c.req.param("id"));
|
|
533
|
+
await ownedProject(c.get("user").id, row.projectId);
|
|
534
|
+
const { value } = z.object({ value: z.string().min(1).max(200) }).parse(await c.req.json());
|
|
535
|
+
return c.json(await addCategoryValue(row.id, value));
|
|
536
|
+
})
|
|
537
|
+
.put("/categories/:id/values/order", async (c) => {
|
|
538
|
+
const row = await categoryRow(c.req.param("id"));
|
|
539
|
+
await ownedProject(c.get("user").id, row.projectId);
|
|
540
|
+
const { ids } = z.object({ ids: z.array(z.string()).max(500) }).parse(await c.req.json());
|
|
541
|
+
await orderCategoryValues(row.id, ids);
|
|
542
|
+
return c.json({ ok: true });
|
|
543
|
+
})
|
|
544
|
+
.get("/values/:id", async (c) => c.json(await valueContents(c.get("user").id, c.req.param("id"))))
|
|
545
|
+
// Everything that has a Kategorie: the entries its page lists.
|
|
546
|
+
.get("/categories/:id/items", async (c) => c.json(await categoryContents(c.get("user").id, c.req.param("id"))))
|
|
547
|
+
.patch("/values/:id", async (c) => {
|
|
548
|
+
const { category } = await categoryValue(c.req.param("id"));
|
|
549
|
+
await ownedProject(c.get("user").id, category.projectId);
|
|
550
|
+
const { value } = z.object({ value: z.string().min(1).max(200) }).parse(await c.req.json());
|
|
551
|
+
await renameCategoryValue(c.req.param("id"), value);
|
|
552
|
+
return c.json({ ok: true });
|
|
553
|
+
})
|
|
554
|
+
.post("/values/:id/merge", async (c) => {
|
|
555
|
+
const { category } = await categoryValue(c.req.param("id"));
|
|
556
|
+
await ownedProject(c.get("user").id, category.projectId);
|
|
557
|
+
const { into } = z.object({ into: z.string() }).parse(await c.req.json());
|
|
558
|
+
await mergeCategoryValues(c.req.param("id"), into);
|
|
559
|
+
return c.json({ ok: true });
|
|
560
|
+
})
|
|
561
|
+
.delete("/values/:id", async (c) => {
|
|
562
|
+
const { category } = await categoryValue(c.req.param("id"));
|
|
563
|
+
await ownedProject(c.get("user").id, category.projectId);
|
|
564
|
+
await deleteCategoryValue(c.req.param("id"));
|
|
565
|
+
return c.json({ ok: true });
|
|
566
|
+
})
|
|
567
|
+
// The Übersicht of a value: a model writes it from the value's items.
|
|
568
|
+
.post("/values/:id/summary", async (c) => {
|
|
569
|
+
const { category } = await categoryValue(c.req.param("id"));
|
|
570
|
+
const project = await ownedProject(c.get("user").id, category.projectId);
|
|
571
|
+
await requireWritable(project);
|
|
572
|
+
return c.json({ summary: await writeSummary(c.req.param("id")) });
|
|
573
|
+
})
|
|
574
|
+
// A Kategorie a person sets on an item: `p:<page>`, `t:<table>`, `r:<row>`, `f:<file>`.
|
|
575
|
+
.put("/projects/:id/items/:key/categories/:categoryId", async (c) => {
|
|
576
|
+
const project = await ownedProject(c.get("user").id, c.req.param("id"));
|
|
577
|
+
await requireWritable(project);
|
|
578
|
+
const key = c.req.param("key");
|
|
579
|
+
const id = key.slice(2);
|
|
580
|
+
const ref = key[0] === "p"
|
|
581
|
+
? { pageId: id }
|
|
582
|
+
: key[0] === "t"
|
|
583
|
+
? { tableId: id }
|
|
584
|
+
: key[0] === "r"
|
|
585
|
+
? { rowId: id }
|
|
586
|
+
: key[0] === "f"
|
|
587
|
+
? { fileId: id }
|
|
588
|
+
: null;
|
|
589
|
+
if (!ref || key[1] !== ":") {
|
|
590
|
+
throw new ServiceError("invalid", "Unbekannter Eintrag.");
|
|
591
|
+
}
|
|
592
|
+
const { values } = z
|
|
593
|
+
.object({ values: z.array(z.union([z.string().max(300), z.number(), z.boolean()])).max(50) })
|
|
594
|
+
.parse(await c.req.json());
|
|
595
|
+
if (await setItemCategory(project.id, ref, c.req.param("categoryId"), values)) {
|
|
596
|
+
queueIndex(key[0] === "p" ? `P:${id}` : key);
|
|
597
|
+
}
|
|
598
|
+
return c.json({ ok: true });
|
|
469
599
|
})
|
|
470
600
|
// --- the space's tables and pages --------------------------------------------
|
|
471
601
|
.get("/projects/:id/data", async (c) => c.json(await listSpaceData(c.get("user").id, c.req.param("id"))))
|
|
@@ -475,6 +605,7 @@ export const studio = new Hono()
|
|
|
475
605
|
title: z.string().max(120),
|
|
476
606
|
wizardId: z.string().nullish(),
|
|
477
607
|
columns: z.unknown().optional(),
|
|
608
|
+
format: z.enum(["faq"]).nullish(),
|
|
478
609
|
})
|
|
479
610
|
.parse(await c.req.json());
|
|
480
611
|
return c.json(await createTable(c.get("user").id, c.req.param("id"), body));
|
|
@@ -486,6 +617,8 @@ export const studio = new Hono()
|
|
|
486
617
|
title: z.string().max(120).optional(),
|
|
487
618
|
wizardId: z.string().nullish(),
|
|
488
619
|
columns: z.unknown().optional(),
|
|
620
|
+
format: z.enum(["faq"]).nullish(),
|
|
621
|
+
review: z.null().optional(),
|
|
489
622
|
})
|
|
490
623
|
.parse(await c.req.json());
|
|
491
624
|
await updateTable(c.get("user").id, c.req.param("id"), body);
|
|
@@ -515,6 +648,7 @@ export const studio = new Hono()
|
|
|
515
648
|
.object({
|
|
516
649
|
title: z.string().max(200),
|
|
517
650
|
wizardId: z.string().nullish(),
|
|
651
|
+
parentId: z.string().nullish(),
|
|
518
652
|
markdown: z.string().optional(),
|
|
519
653
|
})
|
|
520
654
|
.parse(await c.req.json());
|
|
@@ -526,11 +660,18 @@ export const studio = new Hono()
|
|
|
526
660
|
.object({
|
|
527
661
|
title: z.string().max(200).optional(),
|
|
528
662
|
wizardId: z.string().nullish(),
|
|
663
|
+
parentId: z.string().nullish(),
|
|
529
664
|
markdown: z.string().optional(),
|
|
665
|
+
review: z.null().optional(),
|
|
530
666
|
})
|
|
531
667
|
.parse(await c.req.json());
|
|
532
668
|
await updatePage(c.get("user").id, c.req.param("id"), body);
|
|
533
669
|
return c.json({ ok: true });
|
|
670
|
+
})
|
|
671
|
+
.put("/pages/:id/order", async (c) => {
|
|
672
|
+
const { ids } = z.object({ ids: z.array(z.string()).max(5000) }).parse(await c.req.json());
|
|
673
|
+
await orderSubPages(c.get("user").id, c.req.param("id"), ids);
|
|
674
|
+
return c.json({ ok: true });
|
|
534
675
|
})
|
|
535
676
|
.delete("/pages/:id", async (c) => {
|
|
536
677
|
await deletePage(c.get("user").id, c.req.param("id"));
|
|
@@ -639,7 +780,7 @@ export const studio = new Hono()
|
|
|
639
780
|
// What a run of the draft is expected to cost, per step and in total.
|
|
640
781
|
.get("/wizards/:id/estimate", async (c) => {
|
|
641
782
|
const w = await ownedWizard(c.get("user").id, c.req.param("id"));
|
|
642
|
-
return c.json(await estimateRun(w.id, null, w.draft));
|
|
783
|
+
return c.json(await estimateRun(w.id, null, w.draft, await stepsWithoutModel(w.draft)));
|
|
643
784
|
})
|
|
644
785
|
// The models the draft needs that this runtime cannot serve, by class, with the steps that call them.
|
|
645
786
|
.get("/wizards/:id/models", async (c) => {
|
|
@@ -112,14 +112,72 @@ async function spaceDataOf(projectId) {
|
|
|
112
112
|
where: own(schema.spacePage),
|
|
113
113
|
orderBy: [asc(schema.spacePage.id)],
|
|
114
114
|
});
|
|
115
|
+
const categories = await db.query.spaceCategory.findMany({
|
|
116
|
+
where: and(eq(schema.spaceCategory.projectId, projectId), eq(schema.spaceCategory.proposed, false)),
|
|
117
|
+
orderBy: [asc(schema.spaceCategory.position), asc(schema.spaceCategory.id)],
|
|
118
|
+
});
|
|
119
|
+
const values = categories.length
|
|
120
|
+
? await db.query.spaceCategoryValue.findMany({
|
|
121
|
+
where: inArray(schema.spaceCategoryValue.categoryId, categories.map((c) => c.id)),
|
|
122
|
+
orderBy: [asc(schema.spaceCategoryValue.position), asc(schema.spaceCategoryValue.id)],
|
|
123
|
+
})
|
|
124
|
+
: [];
|
|
125
|
+
const assignments = categories.length
|
|
126
|
+
? await db.query.spaceItemCategory.findMany({
|
|
127
|
+
where: and(eq(schema.spaceItemCategory.projectId, projectId), isNull(schema.spaceItemCategory.fileId)),
|
|
128
|
+
orderBy: [asc(schema.spaceItemCategory.id)],
|
|
129
|
+
})
|
|
130
|
+
: [];
|
|
131
|
+
const tableIds = new Set(tables.map((t) => t.id));
|
|
132
|
+
const rowIds = new Set(rows.map((r) => r.id));
|
|
133
|
+
const pageIds = new Set(pages.map((p) => p.id));
|
|
115
134
|
return {
|
|
116
135
|
tables: tables.map((t) => ({
|
|
117
136
|
id: t.id,
|
|
118
137
|
title: t.title,
|
|
138
|
+
format: t.format,
|
|
139
|
+
originLabel: t.originLabel,
|
|
119
140
|
columns: t.columns,
|
|
120
141
|
rows: rows.filter((r) => r.tableId === t.id).map((r) => ({ id: r.id, cells: r.cells })),
|
|
121
142
|
})),
|
|
122
|
-
pages: pages.map((p) => ({
|
|
143
|
+
pages: pages.map((p) => ({
|
|
144
|
+
id: p.id,
|
|
145
|
+
title: p.title,
|
|
146
|
+
markdown: p.markdown,
|
|
147
|
+
parentId: p.parentId,
|
|
148
|
+
position: p.position,
|
|
149
|
+
originLabel: p.originLabel,
|
|
150
|
+
})),
|
|
151
|
+
categories: categories.map((c) => ({
|
|
152
|
+
id: c.id,
|
|
153
|
+
name: c.name,
|
|
154
|
+
type: c.type,
|
|
155
|
+
unit: c.unit,
|
|
156
|
+
multiple: c.multiple,
|
|
157
|
+
ordered: c.ordered,
|
|
158
|
+
hint: c.hint,
|
|
159
|
+
tableId: c.tableId && tableIds.has(c.tableId) ? c.tableId : null,
|
|
160
|
+
columnId: c.tableId && tableIds.has(c.tableId) ? c.columnId : null,
|
|
161
|
+
position: c.position,
|
|
162
|
+
values: values
|
|
163
|
+
.filter((v) => v.categoryId === c.id)
|
|
164
|
+
.map((v) => ({ id: v.id, value: v.value, position: v.position, summary: v.summary })),
|
|
165
|
+
})),
|
|
166
|
+
// Only what goes along: a page, a table or a row of it.
|
|
167
|
+
assignments: assignments
|
|
168
|
+
.filter((a) => (a.pageId && pageIds.has(a.pageId)) ||
|
|
169
|
+
(a.tableId && tableIds.has(a.tableId)) ||
|
|
170
|
+
(a.rowId && rowIds.has(a.rowId)))
|
|
171
|
+
.map((a) => ({
|
|
172
|
+
categoryId: a.categoryId,
|
|
173
|
+
item: a.pageId ? `p:${a.pageId}` : a.tableId ? `t:${a.tableId}` : `r:${a.rowId}`,
|
|
174
|
+
valueId: a.valueId,
|
|
175
|
+
text: a.text,
|
|
176
|
+
num: a.num,
|
|
177
|
+
at: a.at,
|
|
178
|
+
bool: a.bool,
|
|
179
|
+
by: a.by,
|
|
180
|
+
})),
|
|
123
181
|
};
|
|
124
182
|
}
|
|
125
183
|
/**
|