Skip to content

App 16360 add llm 3 d scene generation#740

Merged
mattmacf98 merged 29 commits into
mainfrom
APP-16360-Add-LLM-3D-Scene-generation
Jun 9, 2026
Merged

App 16360 add llm 3 d scene generation#740
mattmacf98 merged 29 commits into
mainfrom
APP-16360-Add-LLM-3D-Scene-generation

Conversation

@sucrammal

Copy link
Copy Markdown
Member

This is a prototype for an LLM-powered frame builder. It allows you to type in a natural language query to edit frame orientation, position, and parent of one or more components in the visualizer.

Here's a short, imperfect demo that shows me moving an arm to a new position, as well as resetting it back to its origin.

basicdemo.mov

Here's another demo of using the frame builder alongside the other editor. Making edits in both ways creates a config diff together.

dragSessionAndFrameBuild.mov

However, I'm having a little trouble with local position vs. world position. I had a peek at the worldPose/worldMatrix implementation, and heard from @mattmacf98 that there was an ongoing bug there. In this demo, an update from the frame builder, although confirmed, does not show a visual preview in its new position. Looking at the component edit tab shows a stale World Position that is only later updated. Not sure if this is because it is waiting for it to update from the network, or something else.

bug.mov

TODOs

  • Investigate world position vs. local position discrepency bug.
  • Currently, the chat is single-shot (i.e. only accepts one prompt at a time, no conversation history). If it's a desirable feature, we can extend the chat functionality.
  • There is no place to place your own LLM provider key. When the visualizer is wired into the app, we can reuse the app/inference routes that are already there. But as suggested by @mattmacf98 , might be easier to have a manual entry in the settings widget for development.
  • General stress testing and robust support simultaneous editing (use frame builder, drag edit session, manual entry).

sucrammal added 6 commits May 29, 2026 17:19
Introduce a new SceneBuilder overlay feature: add SceneBuilder.svelte component, frameDeltaAdapter implementation and unit tests, and a server route (server/routes/scene-builder.ts). Wire the route into server.ts and update +layout.svelte to include the overlay. package.json updated for required dependencies.
Refactor frame-delta workflow to separate validation/preparation from application. Introduces validateProposedFrameDeltas which computes PreparedUpdate records (previous/new pose & parent) and returns errors without mutating config, and add applyPreparedUpdates to apply those prepared updates via updateFrame. Updated tests to cover both validation and application flows, and updated SceneBuilder.svelte to use pendingUpdates, derive diffRows for the preview table, call validateProposedFrameDeltas on submit, and applyPreparedUpdates on confirm (replaced revert->cancel and applied->pendingUpdates naming). Minor debug helper $inspect(localConfigProps, 'LOCAL') added to App.svelte.
@changeset-bot

changeset-bot Bot commented Jun 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 1366025

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@viamrobotics/motion-tools Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@mattmacf98

Copy link
Copy Markdown
Member

this is dope!

@mattmacf98 mattmacf98 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.

This looks great! I left a couple of nits to think about when doing the final PR (I think this is non-invasive enough to just do one PR)

biggest thing is just to move this to a plugin see DrawService for an example on how to do that visualization/src/lib/plugins/DrawService/DrawService.svelte

Comment thread src/routes/api/scene-builder/+server.ts Outdated
Comment thread server/routes/scene-builder.ts
Comment thread server/routes/scene-builder.ts
Comment thread src/routes/api/scene-builder/+server.ts Outdated
Comment thread src/routes/api/scene-builder/+server.ts Outdated
Comment thread src/routes/+layout.svelte Outdated
Comment thread src/lib/components/App.svelte Outdated
() => partID,
() => localConfigProps
)
provideSceneBuilder()

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.

we will probably want to put this provide only in the LLMSceneBuilder plugin, look at how the draw service sets it up

import { provideDrawAPI } from './useDrawAPI.svelte'
as inspo

Comment thread src/lib/components/overlay/SceneBuilder/frameDeltaAdapter.ts Outdated
sucrammal added 6 commits June 2, 2026 09:31
…ally, not viam's OV.

Allow partial Euler orientation updates instead of replacing the full ov_degrees vector. Changes include:

- frameDeltaAdapter: FrameDelta.orientation now accepts optional roll/pitch/yaw and applies Euler deltas to the previous pose (via applyEulerDeltaToPose) rather than overwriting the OV orientation.
- transform: add poseToEulerDegrees and applyEulerDeltaToPose helpers to convert between poses and Euler angles and apply deltas.
- useSceneBuilder: improve diff formatting (rounding for mm/deg) and show per-axis orientation changes (yaw/pitch/roll) using poseToEulerDegrees.
- API (+server): update FrameDelta schema to accept optional roll/pitch/yaw, add field descriptions and enhance the system prompt with coordinate conventions, examples, and guidance to convert Viam orientation vectors to Euler angles.
- Tests: update expectations and add cases covering yaw/pitch application and combining deltas with existing orientations.

These changes make it easier to express incremental, intuitive rotations (e.g. "yaw 90°") and surface axis-specific diffs in the UI.
Comment thread src/lib/hooks/useFrames.svelte.ts Outdated
Comment thread src/lib/transform.ts Outdated
* `Frame.svelte` uses to blend live kinematics with user-staged edits;
* `worldMatrix.ts` premultiplies the result by the parent's `WorldMatrix`.
*/
export const poseToEulerDegrees = (pose: Partial<Pose>): { roll: number; pitch: number; yaw: number } => {

@micheal-parks micheal-parks Jun 2, 2026

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.

Interesting, does the Typescript SDK not expose Viam's euler type signature?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, the TS SDK includes the Euler type signature (https://ts.viam.dev/classes/appRobotApi.Orientation_EulerAngles.html). It's just that Orientation_eulerAngles is defined in radians. The callers of these functions are intentionally in degrees just because degrees are a more natural unit for the end user for frame editing. I could edit this function to use the SDK defined type signature – will just need to add conversions from deg <-> radians. what do you think?

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-06-09 18:41 UTC

@viamrobotics-overwatch

Copy link
Copy Markdown

Hey @sucrammal — CI is green and no reviewer is assigned yet. Could you request one when you have a chance?

Auto-comment from overwatch. Will not re-nudge for 7 days.

@sucrammal sucrammal requested a review from mattmacf98 June 8, 2026 19:00

@mattmacf98 mattmacf98 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.

very close! there are just a couple more extractions to be made to fully plugin-ize this

  1. nothing should go in App.svelte your provideAnthropicKey, LLMSceneBuilder component etc... should just go in the +layout.svelte so they are used in local motion tools without baking them into the exported MotionTools component
  2. pull the AISettings out and inject from the top layer

Comment thread src/lib/hooks/useFrames.svelte.ts Outdated
{ label: 'Vision', component: VisionSettings },
{ label: 'Widgets', component: WidgetSettings },
{ label: 'Debug', component: DebugSettings },
{ label: 'AI', component: AISettings },

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.

move AISettings into the plugin dir for AI and then inject it in via settingsTabs from the top level look at XRSettings as an example https://github.com/viamrobotics/visualization/blob/main/src/routes/%2Blayout.svelte#L70

Comment thread src/lib/components/App.svelte Outdated
<Logs />
<AddFrames />
{#if !localConfigProps || onInfer}
<LLMSceneBuilder onInfer={onInfer ?? standaloneInfer} />

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.

this should not go here, this App gets exported as the component, put it here https://github.com/viamrobotics/visualization/blob/main/src/routes/%2Blayout.svelte#L78-L81 like the other local plugins

</fieldset>
</Portal>

<FloatingPanel

@mattmacf98 mattmacf98 Jun 9, 2026

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.

we can actually put this in <Portal id="dom"> I just found out (instead of having to put in the dashboard snippet

@mattmacf98 mattmacf98 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.

LGTM 3 things before merge

  1. run npx @changesets/cli to create a .changeset minor bump
  2. remove the changes in ‎src/lib/hooks/useFrames.svelte.ts‎
  3. wrap the floatingPanel in <Portal id="dom"> instead of putting in the dashboard snippet

@mattmacf98 mattmacf98 merged commit 64db2c5 into main Jun 9, 2026
8 checks passed
@mattmacf98 mattmacf98 deleted the APP-16360-Add-LLM-3D-Scene-generation branch June 9, 2026 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants