Return modeling commands from KCL execution (#4912)

* Add Rust side artifacts for startSketchOn face or plane

* Add Rust-generated artifacts to ExecOutcome

* Add output of artifact commands

* Add new output files

* Wire the artifact commands to the artifact graph creation

* Fix to use real PartialEq implemented in modeling commands

* Fix modeling commands with zero fields to work

* Fix missing artifactCommands field in errors

* Change artifact graph to be built from artifact commands

* Wire up ExecState artifacts, but not using them yet

Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>

* Remove unneeded local var

* Fix test to fail with a helpful error message when command isn't found

* Rename and deprecate orderedCommands

* Update comment about borrowing

* Move ArtifactCommand tracking to the EngineManager trait

* Update artifact commands since tracking in the engine

* Upgrade kittycad-modeling-cmds from 0.2.85 to 0.2.86

* Remove unneeded JsonSchema derive to speed up build

* Fix to not fail on floating point differences in CI

* Update artifact commands output since truncating floating point numbers

* Fix to ensure artifact commands get cleared after a clear scene

* Update artifact commands snapshot after clearing them on clear scene

* Remove all remnants of OrderedCommands

* Update output for new simulation tests

---------

Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
This commit is contained in:
Jonathan Tran
2025-01-08 20:02:30 -05:00
committed by GitHub
parent eb0850fea9
commit 73a7e2bfd6
121 changed files with 108353 additions and 213 deletions

View File

@ -1,10 +1,10 @@
import {
ArtifactCommand,
defaultRustSourceRange,
defaultSourceRange,
ExecState,
Program,
RustSourceRange,
SourceRange,
sourceRangeFromRust,
} from 'lang/wasm'
import { VITE_KC_API_WS_MODELING_URL, VITE_KC_DEV_TOKEN } from 'env'
import { Models } from '@kittycad/lib'
@ -20,7 +20,6 @@ import { DefaultPlanes } from 'wasm-lib/kcl/bindings/DefaultPlanes'
import {
ArtifactGraph,
EngineCommand,
OrderedCommand,
ResponseMap,
createArtifactGraph,
} from 'lang/std/artifactGraph'
@ -37,6 +36,7 @@ import { KclManager } from 'lang/KclSingleton'
import { reportRejection } from 'lib/trap'
import { markOnce } from 'lib/performance'
import { MachineManager } from 'components/MachineManagerProvider'
import { Node } from 'wasm-lib/kcl/bindings/Node'
// TODO(paultag): This ought to be tweakable.
const pingIntervalMs = 5_000
@ -1303,7 +1303,7 @@ export enum EngineCommandManagerEvents {
*
* As commands are send their state is tracked in {@link pendingCommands} and clear as soon as we receive a response.
*
* Also all commands that are sent are kept track of in {@link orderedCommands} and their responses are kept in {@link responseMap}
* Also all commands that are sent are kept track of in WASM artifactCommands and their responses are kept in {@link responseMap}
* Both of these data structures are used to process the {@link artifactGraph}.
*/
@ -1329,12 +1329,7 @@ export class EngineCommandManager extends EventTarget {
[commandId: string]: PendingMessage
} = {}
/**
* The orderedCommands array of all the the commands sent to the engine, un-folded from batches, and made into one long
* list of the individual commands, this is used to process all the commands into the artifactGraph
*/
orderedCommands: Array<OrderedCommand> = []
/**
* A map of the responses to the {@link orderedCommands}, when processing the commands into the artifactGraph, this response map allow
* A map of the responses to the WASM artifactCommands, when processing the commands into the artifactGraph, this response map allow
* us to look up the response by command id
*/
responseMap: ResponseMap = {}
@ -1830,7 +1825,6 @@ export class EngineCommandManager extends EventTarget {
}
}
async startNewSession() {
this.orderedCommands = []
this.responseMap = {}
await this.initPlanes()
}
@ -2073,28 +2067,6 @@ export class EngineCommandManager extends EventTarget {
isSceneCommand,
}
if (message.command.type === 'modeling_cmd_req') {
this.orderedCommands.push({
command: message.command,
range: sourceRangeFromRust(message.range),
})
} else if (message.command.type === 'modeling_cmd_batch_req') {
message.command.requests.forEach((req) => {
const cmdId = req.cmd_id || ''
const range = cmdId
? sourceRangeFromRust(message.idToRangeMap[cmdId])
: defaultSourceRange()
const cmd: EngineCommand = {
type: 'modeling_cmd_req',
cmd_id: req.cmd_id,
cmd: req.cmd,
}
this.orderedCommands.push({
command: cmd,
range,
})
})
}
this.engineConnection?.send(message.command)
return promise
}
@ -2115,11 +2087,16 @@ export class EngineCommandManager extends EventTarget {
Object.values(this.pendingCommands).map((a) => a.promise)
)
}
updateArtifactGraph(ast: Program) {
updateArtifactGraph(
ast: Node<Program>,
artifactCommands: ArtifactCommand[],
execStateArtifacts: ExecState['artifacts']
) {
this.artifactGraph = createArtifactGraph({
orderedCommands: this.orderedCommands,
artifactCommands,
responseMap: this.responseMap,
ast,
execStateArtifacts,
})
// TODO check if these still need to be deferred once e2e tests are working again.
if (this.artifactGraph.size) {