Skip to content

FE-1985: Add Create entity and Update entity flow actions - #10060

Open
kostandinang wants to merge 6 commits into
mainfrom
kostandin/fe-1985-add-create-entity-and-update-entity-flow-actions
Open

kostandinang wants to merge 6 commits into
mainfrom
kostandin/fe-1985-add-create-entity-and-update-entity-flow-actions

Conversation

@kostandinang

@kostandinang kostandinang commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

🌟 Purpose

Flows can find entities (#10050) but can only write through persistEntity, which takes a full AI-proposed entity. This adds Create Entity and Update Entity, which write through the graph's own API, so the graph does the validation.

  • Create Entity: entityTypeIds (one or more), properties (which may be empty) and an optional draft (default false). properties is the graph's PropertyObjectWithMetadata: values keyed by property type base URL, each with inline metadata (a required dataTypeId, and optionally provenance and confidence). Calls HashEntity.create. Outputs the new entityId, with a draft ID if it's a draft.
  • Update Entity: entityId (an ID or an item of a stored list) and propertyPatches, the graph's add/remove/replace patches. Calls entity.patch(). Outputs the same entityId.
  • Writes in the run's web as the web's machine, on behalf of the user running the flow, as persistEntity does. Update only changes entities the user can edit, and edits the draft if the ID has one.

🔍 Changes

Where What it does
flows/property-values.ts The only checks on our side, run when the flow is defined (for constants) and when the step runs: every value gives a dataTypeId, and each patch targets a whole top-level property. Start here.
flows/action-definitions.ts, flows/types.ts Define both actions and register the PropertyObjectWithMetadata and PropertyPatch kinds.
update-entity-action.ts, create-entity-action.ts The activities: check the inputs, then pass them to the graph unchanged.
shared/save-entity.ts, persist-entity-action.ts The saving actor lookup and retries, moved out of persistEntity so all three share them. No change to persistEntity's behaviour.
generate-uuid.ts generateUuidFromName, for Create's UUID.

Decisions to review:

  • The graph's shapes, not new ones. Metadata is inline, as the graph's create endpoint takes it, rather than in a separate propertyMetadata input. persistEntity's ProposedEntity input isn't reused because it carries AI provenance, claims and link resolution that a value set on a step doesn't have.
  • The graph validates. It checks the entity Create makes, or the entity a patch leaves, including required properties (not for drafts). There's no separate check against the type first.
  • dataTypeId: null is rejected. The graph would accept it and infer a data type, which fails for a property allowing several data types, or only an abstract one.
  • Patches change whole top-level properties, so a retried step changes nothing more. add sets a property, replacing any value. replace fails if the property is missing. remove does nothing if it's already gone. The graph also takes paths inside a value (e.g. a list index), but adding or removing by index isn't safe if Temporal retries the step.
  • Create's entity UUID comes from the run and step IDs, so it's the same on every attempt, including Temporal's retries. Each attempt first looks for that entity and outputs it if an earlier attempt created it, so a retry can't create a second entity.
  • Create doesn't check the user may create an entity of the given types, as persistEntity doesn't. A run only starts if the user has a role in its web, so Create can't write outside the user's webs. Should it check the types too?

⚠️ Known issues

  • Nothing outputs PropertyObjectWithMetadata or PropertyPatch yet, and the run modal doesn't support them, so properties come from constants in the flow definition or flow inputs given programmatically.
  • A save the graph rejects comes back as an internal error with the graph's message, less specific than naming each property. retrySave also retries it, as for persistEntity.
  • Links are out of scope, and Update Entity can't change an entity's types yet. Both are follow-ups, as is replacing persistEntity with Create Entity.

🛡 Tests

  • Create, with a mocked graph: the types and properties passed as given, including several types and no properties; a draft; no entity type IDs, an invalid one, or a value without a data type ID, without creating; a failed save; the same UUID on every attempt; reusing an entity an earlier attempt created.
  • Update, with a mocked graph: the patches passed as given; a draft staying a draft; a stored list item; an invalid or other-web entity ID, no patches, a patch inside a property, or a value without a data type ID, without reading the entity; a missing or unreadable entity; one the user can read but not edit; a failed save.
  • Validator: each shape rule for constant properties and patches, and flow inputs (checked when the step runs).
  • Not yet run end to end through Temporal.

@vercel

vercel Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
hash Ready Ready Preview Oct 21, 2026 2:55pm UTC
petrinaut Ready Ready Preview Oct 21, 2026 2:55pm UTC
2 Skipped Deployments
Project Deployment Actions Updated
hashdotdesign-tokens Ignored Ignored Preview Oct 21, 2026 2:55pm UTC
petrinaut-docs Skipped Skipped Oct 21, 2026 2:55pm UTC

Request Review

@github-actions github-actions Bot added area/apps > hash* Affects HASH (a `hash-*` app) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team type/eng > backend Owned by the @backend team area/apps labels Oct 15, 2026
@codecov

codecov Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.76923% with 25 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.05%. Comparing base (8b1cbc2) to head (f6cb0ab).
⚠️ Report is 10 commits behind head on main.

Files with missing lines Patch % Lines
...c/activities/flow-activities/shared/save-entity.ts 0.00% 11 Missing ⚠️
...ctivities/flow-activities/persist-entity-action.ts 0.00% 6 Missing ⚠️
...hash-isomorphic-utils/src/flows/property-values.ts 90.32% 2 Missing and 4 partials ⚠️
.../@local/hash-isomorphic-utils/src/generate-uuid.ts 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #10060      +/-   ##
==========================================
+ Coverage   68.03%   68.05%   +0.02%     
==========================================
  Files        2006     2010       +4     
  Lines      206233   206406     +173     
  Branches     8796     8851      +55     
==========================================
+ Hits       140312   140471     +159     
- Misses      64253    64255       +2     
- Partials     1668     1680      +12     
Flag Coverage Δ
apps.hash-ai-worker-ts 8.31% <74.24%> (+1.45%) ⬆️
apps.hash-api 15.59% <ø> (ø)
local.hash-backend-utils 6.21% <ø> (ø)
local.hash-isomorphic-utils 33.43% <87.50%> (+1.42%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kostandinang kostandinang self-assigned this Oct 15, 2026
@kostandinang
kostandinang added this pull request to stack #10055 October 15, 2026 22:03
@kostandinang
kostandinang force-pushed the kostandin/fe-1985-add-create-entity-and-update-entity-flow-actions branch from 753313c to 3458b0e Compare October 16, 2026 15:58
@vercel
vercel Bot temporarily deployed to Preview – petrinaut-docs October 16, 2026 15:58 Inactive
@vercel
vercel Bot temporarily deployed to Preview – petrinaut October 16, 2026 15:58 Inactive
@kostandinang
kostandinang force-pushed the kostandin/fe-1985-add-create-entity-and-update-entity-flow-actions branch from 3458b0e to 62f6c20 Compare October 16, 2026 16:09
@vercel
vercel Bot temporarily deployed to Preview – petrinaut October 16, 2026 16:09 Inactive
@vercel
vercel Bot temporarily deployed to Preview – petrinaut-docs October 16, 2026 16:09 Inactive
@vercel
vercel Bot temporarily deployed to Preview – petrinaut-docs October 16, 2026 17:26 Inactive
@vercel
vercel Bot temporarily deployed to Preview – petrinaut October 16, 2026 17:26 Inactive
Create entity creates an entity of a type, with values for some of its properties, in the web the flow runs in. Update entity sets or removes some of an entity's properties, only for a user who can edit it. A created entity keeps the same UUID on every attempt of its step, so a Temporal retry can't create a second one.

Co-authored-by: Cursor <[email protected]>
@kostandinang
kostandinang force-pushed the kostandin/fe-1985-add-create-entity-and-update-entity-flow-actions branch from f714943 to 3cefbe9 Compare October 20, 2026 11:06
@kostandinang
kostandinang requested review from a team as code owners October 20, 2026 11:06
@semgrep-code-hashintel

Copy link
Copy Markdown

Semgrep found 2 node_md5 findings:

  • apps/hash-api/src/mailchimp.ts
  • apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/llama-index/index-pdf-file.ts

🟡 Medium severity issue identified in your code:

MD5 is a a weak hash which is known to have collision. Use a strong hashing function.

Semgrep found 2 crypto-weak-algorithm findings:

  • apps/hash-api/src/mailchimp.ts
  • apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/llama-index/index-pdf-file.ts

🟡 Medium severity issue identified in your code:

The use of a weak cryptographic algorithm (e.g., SHA-1 or MD5) has been identified. These algorithms are considered insecure due to vulnerabilities that make them susceptible to collision attacks, allowing attackers to compromise data integrity or security. Replace SHA-1 or MD5 with secure hashing algorithms, such as: SHA-256 or higher (e.g., SHA-3).

View Dataflow Graph
flowchart LR
    classDef invis fill:white, stroke: none
    classDef default fill:#e7f5ff, color:#1c7fd6, stroke: none

    subgraph File0["<b>apps/hash-api/src/mailchimp.ts</b>"]
        direction LR
        %% Source

        subgraph Source
            direction LR

            v0["<a href=https://github.com/hashintel/hash/blob/3cefbe9fafa7c969515d7d2c2dc342aeceaff0f8/apps/hash-api/src/mailchimp.ts#L41 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 41] &quot;md5&quot;</a>"]
        end
        %% Intermediate

        %% Sink

        subgraph Sink
            direction LR

            v1["<a href=https://github.com/hashintel/hash/blob/3cefbe9fafa7c969515d7d2c2dc342aeceaff0f8/apps/hash-api/src/mailchimp.ts#L41 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 41] &quot;md5&quot;</a>"]
        end
    end
    %% Class Assignment
    Source:::invis
    Sink:::invis

    File0:::invis

    %% Connections

    Source --> Sink

Loading

kostandinang and others added 2 commits October 20, 2026 13:29
Update entity takes the graph's property patches and applies them as given,
and Create entity takes properties with their metadata, so each value names
its data type rather than the graph inferring it. The graph validates both,
so the separate check against the entity's types is removed. Patches change
whole properties, since a patch inside a list isn't safe to retry.

Co-authored-by: Cursor <[email protected]>
CiaranMn
CiaranMn previously approved these changes Oct 21, 2026

@CiaranMn CiaranMn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Some non-blocking comments

Comment thread apps/hash-ai-worker-ts/src/activities/flow-activities/create-entity-action.ts Outdated
Comment thread libs/@local/hash-isomorphic-utils/src/flows/property-values.ts Outdated
Comment thread libs/@local/hash-isomorphic-utils/src/flows/property-values.ts Outdated
entityTypeId,
properties,
draft = false,
} = getSimplifiedFlowActionInputs({ inputs, actionType: "createEntity" });

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

One thing this does not support is the creation of links, which additionally must pass linkData.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, out of scope here. I'll do it as a follow-up.

Comment on lines +82 to +83
{ equal: [{ path: ["uuid"] }, { parameter: entityUuid }] },
{ equal: [{ path: ["webId"] }, { parameter: webId }] },

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just a note that if there is as UUID collision (generally unlikely unless we have duplicate stepIds or runIds for some reason) this would return some other entity.

I appreciate the PR description says we do this in case there's a Temporal retry. I'm not sure that would happen given that the activity is over once the create call succeeds, but probably fine to leave for now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Only retries of the same step run share a UUID, since for-each branches get their own step IDs. Temporal can still retry after the create succeeds if the worker dies before reporting back, so I'll leave it.

@kostandinang

Copy link
Copy Markdown
Contributor Author

Addressed your comments, could you re-approve? The push dismissed your approval.

This branch was successfully deployed

4 active (2 outdated) and 1 inactive deployments
Preview – hash — f6cb0ab4 Deployed Oct 21, 2026 by vercel[bot]
Preview – petrinaut — f6cb0ab4 Deployed Oct 21, 2026 by vercel[bot]
Preview – petrinaut-docs — f6cb0ab4 Deployed Oct 21, 2026 by vercel[bot]
Preview – hashdotdesign-tokens — f7149432 Deployed Oct 19, 2026 by vercel[bot]
pull-request — f7149432 Deployed Oct 19, 2026 by kostandinang via Sourcemaps (@apps/hash-ai-worker-ts) #40389
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/apps > hash* Affects HASH (a `hash-*` app) area/apps area/libs Relates to first-party libraries/crates/packages (area) type/eng > backend Owned by the @backend team type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

2 participants