KJDRAW / AGENT WORKFLOWS
Agent workflows
Let an AI read an authorized drawing, propose exact CAD changes, and hand the final decision to a trusted host.
Build a reviewed CAD workflow#
The @kanjieteam/kjdraw/agent-tools entry point exports KJAgentToolSession, which gives any tool-calling model a controlled way to work with a KJDraw document. It exposes JSON-serializable tool definitions for reading, querying, measuring, checking and proposing CAD changes. Proposal tools return exact geometry for review and do not edit the document.
The host creates the session for one authorized KJDocument, sends selected tool definitions to the model, dispatches model calls through session.call(name, arguments), and keeps approval in its own trusted user interface. The same API works with different model providers; provider connection examples are covered in Models and harnesses.
Capabilities#
- Read the current revision, units, layers, layouts and bounded drawing geometry.
- Query a user selection, object types, layers, owner space or an XY region without sending the entire file.
- Measure explicit points and check stated geometric requirements against native CAD objects.
- Propose editable native geometry and common edits with a before/after preview.
- Apply an approved proposal as one undoable transaction, with revision and argument checks before commit.
- Add project-specific guidance through host-trusted
KJAgentCapabilityRegistrymanifests without adding executable code to the model tool path.
KJDraw enforces the published input schemas again when call() runs. Tool descriptions guide the model, while the CAD core remains responsible for geometry, document revisions, limits and commit behavior.
Install and import#
Install the package in the application that owns the drawing and review UI:
npm install @kanjieteam/kjdraw@next
Import the SDK from the package root and Agent tools from the agent-tools entry point:
import { createKJDrawSDK } from '@kanjieteam/kjdraw'
import { KJAgentToolSession } from '@kanjieteam/kjdraw/agent-tools'
const sdk = createKJDrawSDK()
const drawing = sdk.createDocument({ units: 'millimeter' })
const session = new KJAgentToolSession(sdk, drawing)
session.definitions contains the tools available to that session. Definitions include each tool's name, description, effect and inputSchema; unit fields are restricted to the document's canonical unit name, such as millimeter. Preserve these schema constraints when adapting them to a provider.
The package requires Node.js 22 or later for its Node examples. To verify the installed tool-session path without a model or API key, run:
node node_modules/@kanjieteam/kjdraw/examples/agent-tools.mjs
The example proposes a circle, simulates the host approval step, rejects a duplicate approval, reopens the native file and verifies Undo. It checks integration behavior rather than natural-language drawing quality.
Shortest working flow#
This runnable example creates a session and asks for a circle proposal. The document remains unchanged while the proposal is waiting for review:
import { createKJDrawSDK } from '@kanjieteam/kjdraw'
import {
KJAgentToolSession,
type KJAgentGeometryPreview,
} from '@kanjieteam/kjdraw/agent-tools'
const sdk = createKJDrawSDK()
const drawing = sdk.createDocument({ units: 'millimeter' })
const session = new KJAgentToolSession(sdk, drawing)
const result = await session.call('cad_propose_circles', {
expectedRevision: drawing.revision,
units: 'millimeter',
circles: [{ center: { x: 20, y: 20 }, radius: 3 }],
})
if (!result.ok) throw new Error(`${result.error.code}: ${result.error.message}`)
const proposal = result.value as {
status: 'awaiting-host-approval'
preview: KJAgentGeometryPreview
}
console.log(proposal.status, proposal.preview)
if (drawing.revision !== 0) throw new Error('A proposal must not edit the drawing')
Connect it to a model in four steps:
- Give the provider adapter the selected entries from
session.definitions. - Forward each model tool call to
session.call(name, arguments)and return the result to the same model conversation. - When a proposal succeeds, show its exact arguments and
value.previewto the reviewer. - After the host authenticates the reviewer and checks permission, call
session.approve(planId, reviewerId)orsession.reject(planId, reviewerId)from the host action.
Do not include approve or reject in the model's tool list. A reviewer ID string identifies the decision in KJDraw; authentication and authorization happen in the host application.
Choose the right tool#
Start with the narrowest tool that matches the task. The table lists the common entry points; inspect session.definitions for the complete tool set and its current schemas.
| Tool | Use it for |
|---|---|
cad_read_drawing | Read the first bounded page of visible model-space objects, layers, units and revision |
cad_read_page | Continue the unfiltered read with the returned entity and layer offsets |
cad_read_layouts | Discover model and paper layouts, exact owner-space IDs and numeric page settings |
cad_query_drawing | Read a revision-bound page filtered by ID, type, layer, owner space or XY bounds |
cad_measure_distance | Calculate an exact planar distance between two supplied points in drawing units |
cad_check_geometry | Compare explicit lengths, radii, feature distances or topology checks with native objects |
cad_propose_lines | Propose 1–64 model-space XY lines |
cad_propose_circles | Propose 1–64 model-space XY circles |
cad_propose_move | Propose one XY move for supported visible, editable objects or a named selection set |
cad_propose_drawing | Propose a mixed batch of native lines, circles, arcs, ellipses, splines, polylines and hatches |
Use cad_read_drawing when the model needs an initial overview. Use cad_query_drawing for a user selection or a known region, and continue with identical filters plus the returned nextOffset and nextLayerOffset. Call cad_read_layouts first when paper space is involved, then pass its exact spaceId to cad_query_drawing. cad_read_page continues only an unfiltered read and does not remember query filters.
Use cad_check_geometry only after reading the real object IDs. An unmet requirement returns ok: true with value.passed: false: the tool executed successfully and the geometry failed the requested check. The result proves only the expectations and tolerances supplied by the host; it does not certify a complete design.
Choose a specific proposal tool for a focused edit. Use cad_propose_drawing for a mixed batch; the installed examples/agent-drawing.mjs builds a profile with holes and a slot, then verifies preview, approval, file reopen and history. More specialized proposal tools in session.definitions cover transforms, compact patterns, annotations and packaged engineering workflows.
Native coordinates can be object-local or block-local. Read tools do not expand block definitions or promise world coordinates, and XY bounds are drawing coordinates rather than screen pixels or paper viewport projections. Treat spatialMatch: 'unclassified' as requiring inspection, never as proof that an object intersects the requested region.
Direct host-side drawing context#
If the host needs drawing data outside a model tool loop, use the same bounded query implementation directly. createLayoutContext(document, options) provides the corresponding immutable layout catalog.
import { createKJDrawSDK } from '@kanjieteam/kjdraw'
import { createDrawingContext } from '@kanjieteam/kjdraw/drawing-context'
const sdk = createKJDrawSDK()
const drawing = sdk.createDocument({ units: 'millimeter' })
await sdk.executeCommand('CREATE', {
type: 'CIRCLE', payload: { center: [20, 30, 0], radius: 4 },
})
const context = createDrawingContext(drawing, {
types: ['CIRCLE'],
expectedRevision: drawing.revision,
limit: 20,
maxLayers: 0,
maxBytes: 16_384,
})
// context.entities contains native geometry, IDs and editing eligibility.
// Reading context does not change the drawing or contact a model.
Review and apply proposals#
Every successful proposal contains the document ID, expected revision, normalized arguments, a planId and exact before/after geometry in value.preview. Render that preview over the current drawing and show the proposed parameters. If the camera changes, redraw the overlay from the stored preview.
Approval is a one-shot host operation. KJDraw checks that the plan is still pending, the bound document and revision are unchanged, and the committed geometry matches the reviewed proposal. A successful commit becomes one normal Undo step. Rejecting a proposal consumes it without changing the drawing.
For lower-level SDK commands, the equivalent protocol uses sdk.createCommandEnvelope(..., { mode: 'plan', origin: 'ai' }), followed by a confirmed execution envelope after review. Keep the plan ID, command arguments and document revision unchanged between these steps.
Preview and apply a trim#
The boundary-editing API can preview the exact retained geometry used by the workbench Trim/Extend tools. The example below creates a circle and cutting line, then proposes keeping the lower semicircle as an editable ARC:
import { createKJDrawSDK } from '@kanjieteam/kjdraw'
import { createBoundaryEditSession } from '@kanjieteam/kjdraw/boundary-edit'
const sdk = createKJDrawSDK()
const drawing = sdk.createDocument({ units: 'millimeter' })
const boundary = await sdk.executeCommand<{ id: string }>('CREATE', {
type: 'LINE', payload: { start: [-15, 0, 0], end: [15, 0, 0] },
})
const circle = await sdk.executeCommand<{ id: string }>('CREATE', {
type: 'CIRCLE', payload: { center: [0, 0, 0], radius: 10 },
})
const edit = createBoundaryEditSession('trim', {
document: drawing, boundaryIds: [boundary.id],
})
edit.confirmBoundaries()
const geometry = edit.preview(circle.id, [0, 10])
// geometry.pieces contains the retained ARC; no document mutation occurred.
// With a mounted KJCanvasRenderer: renderer.drawPreview(geometry.pieces).
const plan = sdk.createCommandEnvelope(
geometry.command.command, geometry.command.arguments,
{ document: drawing, expectedRevision: geometry.revision, origin: 'ai', mode: 'plan' },
)
await sdk.executeCommandEnvelope(plan, { document: drawing })
Present geometry.pieces with the original drawing. Call the following function only from the host's approval action, using the authenticated reviewer's identity:
async function applyApprovedTrim(confirmedBy: string) {
const receipt = await edit.apply(geometry, request =>
sdk.executeCommandEnvelope(sdk.createCommandEnvelope(
request.command, request.arguments, {
document: drawing, expectedRevision: request.expectedRevision, origin: 'ai',
confirmation: { status: 'confirmed', planId: plan.id, confirmedBy },
},
), { document: drawing }),
)
edit.finish()
return receipt
}
Reject with sdk.agentPlans.reject(plan.id, reviewerId) and edit.cancel(). Keep the original in-process preview object until review ends; create a new preview after any document change.
Handle errors and enforce boundaries#
session.call() resolves to a discriminated result. Read value only when ok is true; otherwise log the stable error.code and show an action-oriented message to the user.
| Result | Host response |
|---|---|
KJDOCUMENT_REVISION_CONFLICT | Re-read the drawing and ask the model to produce a new proposal against the new revision |
KJDOCUMENT_INVALID | Correct the tool name or arguments using this session's definition; do not retry unchanged input |
KJAGENT_TOOL_FAILED | Stop automatic retries and let the host inspect the underlying failure |
Successful read with value.passed: false | Report the failed geometric checks; do not convert it into a successful design result |
The session permits one operation at a time and at most 128 proposals. Individual definitions set their own object, byte and pagination limits. Start a new session only when the host intentionally begins a new authorized work period; do not use session replacement to bypass a rejected or stale plan.
These boundaries always remain with the host application:
- Authorize which document and drawing data the model may access.
- Authenticate reviewers and enforce project or organization permissions.
- Keep
approve,reject, file access, network access and arbitrary command execution out of the model tool list. - Preserve user-approved dimensions, tolerances and requirements; model text is not execution evidence.
- Set model budgets, timeouts, data-retention rules and provider-specific disclosure controls.
- Store receipts or approval records when a durable audit trail is required.
KJDraw validates tool inputs and reviewed CAD mutations inside one SDK host process. It does not sandbox a model, authenticate users, enforce policy across services or certify engineering fitness. Failed or uncertain approval attempts must be inspected and must not be retried automatically.
For the lifecycle and trust model, read the Agent integration contract and Agent protocol.