Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eval/datasets/workspace-tools.cases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const workspaceToolCases: WorkspaceToolCase[] = [
"workspace_delete_items",
"workspace_create_items",
"workspace_edit_item",
"workspace_link_items",
"workspace_move_items",
"workspace_rename_item",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,39 +56,6 @@ exports[`workspace tool surface > workspace_create_items input schema is stable
"minLength": 1,
"type": "string",
},
"relations": {
"description": "Optional relationships from this new folder to other workspace items, at most 20.",
"items": {
"additionalProperties": false,
"properties": {
"kind": {
"description": "\`derived_from\` means this item was created or materially changed from the linked item. \`references\` means this item cites or points to the linked item.",
"enum": [
"derived_from",
"references",
],
"type": "string",
},
"note": {
"description": "Optional short source detail, like pages 12-14 or section on photosynthesis.",
"maxLength": 240,
"type": "string",
},
"path": {
"description": "Absolute path of the related ThinkEx workspace item.",
"minLength": 1,
"type": "string",
},
},
"required": [
"kind",
"path",
],
"type": "object",
},
"maxItems": 20,
"type": "array",
},
"type": {
"const": "folder",
"type": "string",
Expand All @@ -114,39 +81,6 @@ exports[`workspace tool surface > workspace_create_items input schema is stable
"minLength": 1,
"type": "string",
},
"relations": {
"description": "Optional relationships from this new document to other workspace items, at most 20.",
"items": {
"additionalProperties": false,
"properties": {
"kind": {
"description": "\`derived_from\` means this item was created or materially changed from the linked item. \`references\` means this item cites or points to the linked item.",
"enum": [
"derived_from",
"references",
],
"type": "string",
},
"note": {
"description": "Optional short source detail, like pages 12-14 or section on photosynthesis.",
"maxLength": 240,
"type": "string",
},
"path": {
"description": "Absolute path of the related ThinkEx workspace item.",
"minLength": 1,
"type": "string",
},
},
"required": [
"kind",
"path",
],
"type": "object",
},
"maxItems": 20,
"type": "array",
},
"type": {
"const": "document",
"type": "string",
Expand All @@ -163,7 +97,7 @@ exports[`workspace tool surface > workspace_create_items input schema is stable
"description": "Flashcard set to create.",
"properties": {
"cards": {
"description": "Ordered cards. Flashcard fronts and backs are HTML. Keep each side concise. Use paragraphs, lists, links, code blocks, and standard text marks only. This is HTML, so math is markup rather than delimiters: use <span data-type="inline-math" data-latex="..."></span> or <div data-type="block-math" data-latex="..."></div>, and keep dollar signs out of the data-latex value. Put every subscript and superscript (exponents like 10^8, indices like x_1) inside math rather than <sub>/<sup> tags. Chemistry renders with \\ce{...} (e.g. \\ce{CH4 + 2 O2 -> CO2 + 2 H2O}) and quantities with units render with \\pu{...} (e.g. \\pu{9.81 m/s^2}), both inside data-latex. Write literal money as plain text ($30, never \\$30) — a backslash before a dollar sign shows on screen in HTML. A code block carries its language as a class on the inner <code>: <pre><code class="language-python">…</code></pre>. Without that class the block renders unhighlighted and unlabelled. Do not use headings, tables, images, widgets, task lists, or citations inside a card. Use item-level relations for sources.",
"description": "Ordered cards. Flashcard fronts and backs are HTML. Keep each side concise. Use paragraphs, lists, links, code blocks, and standard text marks only. This is HTML, so math is markup rather than delimiters: use <span data-type="inline-math" data-latex="..."></span> or <div data-type="block-math" data-latex="..."></div>, and keep dollar signs out of the data-latex value. Put every subscript and superscript (exponents like 10^8, indices like x_1) inside math rather than <sub>/<sup> tags. Chemistry renders with \\ce{...} (e.g. \\ce{CH4 + 2 O2 -> CO2 + 2 H2O}) and quantities with units render with \\pu{...} (e.g. \\pu{9.81 m/s^2}), both inside data-latex. Write literal money as plain text ($30, never \\$30) — a backslash before a dollar sign shows on screen in HTML. A code block carries its language as a class on the inner <code>: <pre><code class="language-python">…</code></pre>. Without that class the block renders unhighlighted and unlabelled. Do not use headings, tables, images, widgets, task lists, or citations inside a card.",
"items": {
"additionalProperties": false,
"properties": {
Expand Down Expand Up @@ -195,39 +129,6 @@ exports[`workspace tool surface > workspace_create_items input schema is stable
"minLength": 1,
"type": "string",
},
"relations": {
"description": "Optional relationships from this set to source items, at most 20.",
"items": {
"additionalProperties": false,
"properties": {
"kind": {
"description": "\`derived_from\` means this item was created or materially changed from the linked item. \`references\` means this item cites or points to the linked item.",
"enum": [
"derived_from",
"references",
],
"type": "string",
},
"note": {
"description": "Optional short source detail, like pages 12-14 or section on photosynthesis.",
"maxLength": 240,
"type": "string",
},
"path": {
"description": "Absolute path of the related ThinkEx workspace item.",
"minLength": 1,
"type": "string",
},
},
"required": [
"kind",
"path",
],
"type": "object",
},
"maxItems": 20,
"type": "array",
},
"type": {
"const": "flashcard",
"type": "string",
Expand Down Expand Up @@ -427,7 +328,7 @@ exports[`workspace tool surface > workspace_edit_item input schema is stable 1`]
"description": "Flashcard edits.",
"properties": {
"edits": {
"description": "Ordered flashcard edits using exact refs from a read. Available operations: insert_before, insert_after, update, replace, replace_text, move, and delete. replace changes both sides; replace_text requires front or back as side; move requires exactly one of beforeRef or afterRef. Flashcard fronts and backs are HTML. Keep each side concise. Use paragraphs, lists, links, code blocks, and standard text marks only. This is HTML, so math is markup rather than delimiters: use <span data-type="inline-math" data-latex="..."></span> or <div data-type="block-math" data-latex="..."></div>, and keep dollar signs out of the data-latex value. Put every subscript and superscript (exponents like 10^8, indices like x_1) inside math rather than <sub>/<sup> tags. Chemistry renders with \\ce{...} (e.g. \\ce{CH4 + 2 O2 -> CO2 + 2 H2O}) and quantities with units render with \\pu{...} (e.g. \\pu{9.81 m/s^2}), both inside data-latex. Write literal money as plain text ($30, never \\$30) — a backslash before a dollar sign shows on screen in HTML. A code block carries its language as a class on the inner <code>: <pre><code class="language-python">…</code></pre>. Without that class the block renders unhighlighted and unlabelled. Do not use headings, tables, images, widgets, task lists, or citations inside a card. Use item-level relations for sources.",
"description": "Ordered flashcard edits using exact refs from a read. Available operations: insert_before, insert_after, update, replace, replace_text, move, and delete. replace changes both sides; replace_text requires front or back as side; move requires exactly one of beforeRef or afterRef. Flashcard fronts and backs are HTML. Keep each side concise. Use paragraphs, lists, links, code blocks, and standard text marks only. This is HTML, so math is markup rather than delimiters: use <span data-type="inline-math" data-latex="..."></span> or <div data-type="block-math" data-latex="..."></div>, and keep dollar signs out of the data-latex value. Put every subscript and superscript (exponents like 10^8, indices like x_1) inside math rather than <sub>/<sup> tags. Chemistry renders with \\ce{...} (e.g. \\ce{CH4 + 2 O2 -> CO2 + 2 H2O}) and quantities with units render with \\pu{...} (e.g. \\pu{9.81 m/s^2}), both inside data-latex. Write literal money as plain text ($30, never \\$30) — a backslash before a dollar sign shows on screen in HTML. A code block carries its language as a class on the inner <code>: <pre><code class="language-python">…</code></pre>. Without that class the block renders unhighlighted and unlabelled. Do not use headings, tables, images, widgets, task lists, or citations inside a card.",
"items": {
"anyOf": [
{
Expand Down Expand Up @@ -636,38 +537,54 @@ exports[`workspace tool surface > workspace_link_items input schema is stable 1`
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"path": {
"description": "Absolute path of the workspace item to link from.",
"minLength": 1,
"type": "string",
},
"relations": {
"description": "Relationships from this item to other workspace items, at most 20.",
"items": {
"description": "One or more existing items to link from, at most 20. Each can have up to 20 relations.",
"items": {
"additionalProperties": false,
"properties": {
"kind": {
"description": "\`derived_from\` means this item was created or materially changed from the linked item. \`references\` means this item cites or points to the linked item.",
"enum": [
"derived_from",
"references",
],
"type": "string",
},
"note": {
"description": "Optional short source detail, like pages 12-14 or section on photosynthesis.",
"maxLength": 240,
"type": "string",
},
"path": {
"description": "Absolute path of the related ThinkEx workspace item.",
"description": "Absolute path of the workspace item to link from.",
"minLength": 1,
"type": "string",
},
"relations": {
"description": "Relationships from this item to other workspace items, at most 20.",
"items": {
"additionalProperties": false,
"properties": {
"kind": {
"description": "\`derived_from\` means this item was created or materially changed from the linked item. \`references\` means this item cites or points to the linked item.",
"enum": [
"derived_from",
"references",
],
"type": "string",
},
"note": {
"description": "Optional short source detail, like pages 12-14 or section on photosynthesis.",
"maxLength": 240,
"type": "string",
},
"path": {
"description": "Absolute path of the related ThinkEx workspace item.",
"minLength": 1,
"type": "string",
},
},
"required": [
"kind",
"path",
],
"type": "object",
},
"maxItems": 20,
"minItems": 1,
"type": "array",
},
},
"required": [
"kind",
"path",
"relations",
],
"type": "object",
},
Expand All @@ -677,8 +594,7 @@ exports[`workspace tool surface > workspace_link_items input schema is stable 1`
},
},
"required": [
"path",
"relations",
"items",
],
"type": "object",
}
Expand Down
28 changes: 3 additions & 25 deletions src/features/workspaces/operations/create-items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import {
createWorkspaceItem,
resolveWorkspacePaths,
} from "#/features/workspaces/persistence/workspace-items";
import {
resolveWorkspaceRelations,
type WorkspaceRelationInput,
} from "#/features/workspaces/operations/relations";
import { createWorkspaceItemsFailureCodes } from "#/features/workspaces/operations/workspace-operation-failure-codes";
import type { WorkspaceAccessContext } from "#/features/workspaces/operations/workspace-access-context";
import type { WorkspacePathResolution } from "#/features/workspaces/persistence/workspace-persistence-types";
Expand Down Expand Up @@ -34,18 +30,16 @@ import {
} from "#/features/workspaces/model/workspace-paths";

export type CreateWorkspaceItemOperationInput =
| { type: "folder"; path: string; relations?: WorkspaceRelationInput[] }
| { type: "folder"; path: string }
| {
type: "document";
path: string;
initialContent?: string;
relations?: WorkspaceRelationInput[];
}
| {
type: "flashcard";
path: string;
cards: Array<{ front: string; back: string }>;
relations?: WorkspaceRelationInput[];
};

export interface CreateWorkspaceItemsOperationInput {
Expand Down Expand Up @@ -111,9 +105,9 @@ export async function createWorkspaceItemsOperation(
continue;
}

const [parentResolution, ...relationTargets] = await resolveWorkspacePaths({
const [parentResolution] = await resolveWorkspacePaths({

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/async-await-in-loop (warning)

This makes the for…of loop slow because each await runs one after another, so collect the independent calls & run them together with await Promise.all(items.map(...))

Fix → Collect the items, then use await Promise.all(items.map(...)) so independent work runs at the same time

Docs

workspaceId: accessContext.workspaceId,
paths: [path.parentPath, ...(itemInput.relations ?? []).map((relation) => relation.path)],
paths: [path.parentPath],
});
if (!parentResolution) {
throw new Error("Workspace persistence did not resolve the requested create parent.");
Expand Down Expand Up @@ -151,21 +145,6 @@ export async function createWorkspaceItemsOperation(
continue;
}

const relations = resolveWorkspaceRelations({
fromItemId: id,
relations: itemInput.relations,
targets: relationTargets,
});

if (relations.status === "failed") {
failed.push({
code: relations.failure.code,
index,
path: relations.failure.path,
});
continue;
}

const { env } = await import("cloudflare:workers");
const outcome = await createWorkspaceItem(env, {
id,
Expand All @@ -175,7 +154,6 @@ export async function createWorkspaceItemsOperation(
name: path.name,
onNameConflict: "error",
initialContent: initialContent.content,
initialRelations: relations.relations,
actorUserId: accessContext.actor.userId,
});

Expand Down
Loading