KJDrawDocs

KJDRAW / CONNECT YOUR MODEL

Connect your model

Bring your model, gateway or agent framework. Keep one CAD engine and one set of drawing tools.

Choose a connection

KJDraw does not require a particular AI vendor. Choose a protocol adapter, supply your model and host transport, and run the same CAD tools. A custom KJAgentModel connects frameworks, local models or other protocols without changing the drawing engine.

Agent and client matrix

The drawing contract is independent of the model vendor. A client that can launch an stdio MCP server can use the same KJDraw tools; clients without native MCP support can connect through an MCP-capable host or call the TypeScript adapter directly.

Client or model familyRecommended pathWhat changesWhat stays the same
OpenAI CodexRegister the kjdraw stdio server in Codex MCP settingsClient configuration onlyTool names, proposals and approval boundary
Claude Desktop, Cursor, ClineAdd the same server entry to the client's MCP configurationClient configuration onlyKJD/DXF document contract
Kimi Code, WorkBuddy, ZCode, TraeCodeRun the user-level installer and follow the client's import promptClient configuration and one-time importLocal files and host approval
Doubao, DeepSeek and other domestic modelsUse an MCP-capable host, or pass their tool-call JSON through createKJModelAdapter / createKJDomesticModelAdapterProvider endpoint and transportCAD tools, validation and receipts
Custom harness, gateway or private modelImplement KJAgentModel or expose the stdio server from the hostYour conversation loop and credentialsThe KJDraw agent session and document model

Portable MCP entry for a locally built package containing kjdraw-mcp.mjs: create proposals and results in the host project and replace both absolute-path placeholders. Verify the installed npm version first; next may still resolve to an older candidate without this executable.

{
  "mcpServers": {
    "kjdraw": {
      "command": "node",
      "args": ["/absolute/project/node_modules/@kanjieteam/kjdraw/bin/kjdraw-mcp.mjs", "--workspace", "/absolute/project", "--blank", "drawing.kjd", "--units", "millimeter", "--proposal-dir", "proposals", "--candidate-dir", "results"]
    }
  }
}

KJDraw does not discover provider keys, choose network endpoints or approve edits. Keep those responsibilities in the client or host and treat model text as untrusted input.

ConnectionAdapter valueHost transport
OpenAI ResponsesresponsesResponses REST endpoint
Chat Completions-compatible serviceschat-completionsThe selected service's compatible endpoint; DeepSeek is one evaluation option
Claude Messagesanthropic-messagesMessages REST endpoint
Gemini GenerateContentgemini-generate-contentGenerateContent REST endpoint, with model in the URL
Your framework, gateway or local modelCustom KJAgentModelYour own conversation bridge

The built-in adapters support the protocols listed above. Compatibility with a particular model or vendor extension depends on that endpoint's function-calling behavior. For text-only models, a custom bridge can parse and validate a structured response; never execute model-generated JavaScript.

Wire the model once

Install KJDraw, then import the model adapter and bounded task runner from their public package entries:

import { createKJDrawSDK } from '@kanjieteam/kjdraw'
import { KJAgentToolSession } from '@kanjieteam/kjdraw/agent-tools'
import { createKJModelAdapter } from '@kanjieteam/kjdraw/model-adapters'
import { runKJAgentTask } from '@kanjieteam/kjdraw/agent-runner'

const sdk = createKJDrawSDK()
const drawing = sdk.createDocument({ units: 'millimeter' })
const session = new KJAgentToolSession(sdk, drawing)
const model = createKJModelAdapter({
  protocol: 'chat-completions',
  model: selectedModel,
  request: ({ body, signal }) => hostModelGateway(body, signal),
})
const result = await runKJAgentTask({
  session,
  model,
  prompt: 'Propose a circle at (20, 25) mm with a radius of 3 mm.',
  toolNames: ['cad_read_drawing', 'cad_propose_circles'],
  maxTurns: 8,
  maxToolCalls: 32,
})

selectedModel and hostModelGateway belong to your application. The gateway returns parsed, non-streaming provider JSON and rejects HTTP failures. For Gemini, send the body to the configured model URL; this is a REST adapter, not the Google SDK's nested config argument. Keep keys, endpoint allowlists and user permissions on your server. The CAD package does not discover keys, choose an endpoint or send network requests by itself.

Chat-compatible endpoints differ in output token fields: the default is max_tokens; set chatTokenParameter: 'max_completion_tokens' when required. The other adapters map maxOutputTokens to their protocol. Full runtime argument validation remains enabled; Responses explicitly uses non-strict tool generation rather than promising identical provider-side schema support.

Doubao through Volcengine Ark

The source-tree adapter accepts provider doubao on Ark's Chat Completions protocol. Your trusted host supplies the model ID, HTTPS transport and ARK_API_KEY; KJDraw never reads that key. Ark's documented base URL is https://ark.cn-beijing.volces.com/api/v3 and the request path is /chat/completions. Enable tool calling on a model that supports it. The adapter preserves an assistant's encrypted reasoning block across tool-result turns, including a complete block delivered in a streaming response.

import { createKJDomesticModelAdapter } from '@kanjieteam/kjdraw/domestic-model-profiles'

const model = createKJDomesticModelAdapter({ provider: 'doubao', model: selectedArkModelId, reasoning: { mode: 'enabled' }, request: ({ body, signal }) => callTrustedArkGateway(body, signal), })

The model ID and gateway function above are provided by your host. The Ark Chat API and thinking/tool-call guide define the wire fields. Local protocol fixtures pass, but no live Ark account or specific model has been certified by those tests.

Choose tools for a task

toolNames is an optional host policy for one run. Omit it to retain all session tools. Supply a nonempty list of unique exact names from session.definitions; unknown names, duplicates and empty lists fail before opening a model conversation. Definitions retain their canonical order and complete schemas, including drawing units. The runner snapshots the selection before invoking the model, so later array changes cannot widen access.

Every adapter and custom bridge receives the same selected definitions. If a response requests an omitted tool, the runner returns failed with KJAGENT_TOOL_NOT_ALLOWED before dispatching any call in that batch. The next run selects its own policy. This does not restrict trusted host calls made directly on the session, replace authentication, or allow the model to approve proposals. Include reading and pagination tools when the task needs them. Smaller schemas reduce JSON bytes; actual model token counts and task success still require provider measurements.

Review the result

StatusWhat the host should do
awaiting-approvalDisplay the exact proposals in outputs; use proposalIds to approve or reject from your review UI
respondedShow the model's answer or clarification; it is not evidence that a drawing task succeeded
limit-reachedInspect results and adjust the task or budget; do not automatically retry forever
cancelledThe host cancelled or the run timed out; late model calls are not dispatched
failedHandle the structured error; inspect private transport diagnostics on the server

The runner stops when it has proposals. It never calls approve(). After an authenticated user reviews the exact arguments, your host calls session.approve(planId, user.id) or session.reject(planId, user.id) and checks the result. Model text must be displayed as untrusted text, not unsanitized HTML.

Each run starts from the drawing's current revision. After applying a proposal, submit the next request as a new run so the model reads the updated geometry. Your application owns conversation persistence and save policy. See Agent workflows for CAD tools, proposal previews and geometry checks.

To expose the same tool registry through a packaged local stdio server, follow the MCP integration guide. It includes persistent client configuration, a real JSON-RPC call and the host-controlled file and approval boundary.

Measure tokens and time

result.measurements retains each attempted turn's usage, normalized totals, transport wall time and runner wall time. Counters come from provider response fields; missing or invalid counters remain null. Cache and reasoning counters are subsets or additional components according to each protocol, so they are not blindly added twice. A cancelled request without a received response has missing usage. complete describes observed token counters, not design completion or a billing receipt.

const { totals, transportWallMs, runWallMs, complete } = result.measurements
// Keep null as unavailable; do not replace it with zero in a benchmark.
console.log({ totals, transportWallMs, runWallMs, complete })

Adapters also accept onUsage: usage => hostMetrics.record(usage) for response observations, including rejected or truncated responses. Observer failures do not change drawing behavior. A late response after cancellation may still reach that host observer; it cannot rewrite the runner's returned measurement snapshot. extractKJModelUsage is available from /model-usage for a custom transport. No response text, credentials, inferred token counts or prices are included. Controlled live-model comparisons still require repeated matched tasks and actual provider configuration.

Run the packaged example

node node_modules/@kanjieteam/kjdraw/examples/model-agent.mjs

By default, the example runs offline and demonstrates all four wire formats, host approval, saved geometry and undo without contacting a model.

To connect an online model, configure KJDRAW_MODEL_PROTOCOL, KJDRAW_MODEL_NAME, KJDRAW_MODEL_ENDPOINT and KJDRAW_MODEL_API_KEY in a trusted server or CLI environment, then add --live. The endpoint is the complete trusted REST URL. The example rejects redirects and URL credentials, limits response bytes and never applies live proposals automatically. It sends at most four model requests and eight tool calls; provider charges may apply.

Extend and validate

Implement KJAgentModel.createConversation({ instructions, tools }) and return next(input, signal). A turn returns text plus calls containing id, name and arguments. Inputs are either the initial prompt or ordered tool results. Keep vendor continuation data private to that conversation and preserve call/result IDs. Existing Agent runtimes can also use KJAgentToolSession directly and manage their own execution loop.

Adapters retain Responses reasoning items, chat reasoning fields, Claude signed thinking blocks and Gemini thought signatures in their original conversation. They do not place those fields in the public answer. Truncated, blocked, malformed or unsupported responses stop before tool dispatch. Tool validation errors can be returned to the model for bounded correction. Timeouts cannot stop a transport that ignores its signal from consuming remote resources; the host must enforce its own network and billing limits.

Protocol references: OpenAI function calling, DeepSeek tool calls, Claude tool results, Gemini GenerateContent.

KJDRAW / 接入你的模型

接入你的模型

接入你选择的模型、网关或 Agent 框架,共用一套 CAD 引擎与绘图工具。

选择接入方式

KJDraw 不依赖特定 AI 厂商。选择协议适配器,传入模型和宿主请求函数,就能使用同一套 CAD 工具。其他框架、本地模型或协议可实现 KJAgentModel,无需修改绘图引擎。

智能体与客户端接入矩阵

图档和工具契约不绑定模型厂商。能启动 stdio MCP server 的客户端可以直接使用同一套 KJDraw 工具;不原生支持 MCP 的客户端,可通过支持 MCP 的宿主转接,或直接调用 TypeScript 适配器。

客户端或模型家族推荐路径变化的部分保持不变的部分
OpenAI Codex在 Codex MCP 设置中注册 kjdraw stdio server客户端配置工具名、提案和审批边界
Claude Desktop、Cursor、Cline在客户端 MCP 配置中加入同一 server客户端配置KJD/DXF 图档契约
Kimi Code、WorkBuddy、ZCode、TraeCode运行用户级安装器,按提示完成一次导入客户端配置与一次导入本地文件和宿主审批
豆包、DeepSeek 及其他国产模型通过支持 MCP 的宿主接入,或把工具调用 JSON 交给 createKJModelAdapter / createKJDomesticModelAdapter模型接口和传输层CAD 工具、校验和回执
自建 Harness、网关或私有模型实现 KJAgentModel,或由宿主暴露 stdio server会话循环和凭据管理KJDraw Agent 会话和图档模型

本地构建且包含 kjdraw-mcp.mjs 的包可使用以下配置:先在宿主工程创建 proposals 和 results 目录,替换两处绝对路径;npm next 仍可能是没有该命令的旧候选版,接入前须先核对实际安装版本。

{
  "mcpServers": {
    "kjdraw": {
      "command": "node",
      "args": ["/absolute/project/node_modules/@kanjieteam/kjdraw/bin/kjdraw-mcp.mjs", "--workspace", "/absolute/project", "--blank", "drawing.kjd", "--units", "millimeter", "--proposal-dir", "proposals", "--candidate-dir", "results"]
    }
  }
}

KJDraw 不会搜索模型密钥、选择网络地址或批准修改;这些职责由客户端或宿主承担,模型文本始终按不可信输入处理。

接入方式适配器值宿主请求目标
OpenAI ResponsesresponsesResponses REST 接口
Chat Completions 兼容服务chat-completions所选服务的兼容接口;DeepSeek 只是测试选项之一
Claude Messagesanthropic-messagesMessages REST 接口
Gemini GenerateContentgemini-generate-contentGenerateContent REST 接口,模型名放在 URL 中
自有框架、网关、本地模型自定义 KJAgentModel你的会话桥接实现

内置适配器支持上表所列协议;具体模型和厂商扩展字段的兼容性取决于对应接口的工具调用行为。纯文本模型可通过自定义桥接解析并校验结构化结果,但不能执行模型输出的 JavaScript。

配置一次模型连接

安装 KJDraw 后,从公开子路径导入模型适配器和有界任务运行器:

import { createKJDrawSDK } from '@kanjieteam/kjdraw'
import { KJAgentToolSession } from '@kanjieteam/kjdraw/agent-tools'
import { createKJModelAdapter } from '@kanjieteam/kjdraw/model-adapters'
import { runKJAgentTask } from '@kanjieteam/kjdraw/agent-runner'

const sdk = createKJDrawSDK()
const drawing = sdk.createDocument({ units: 'millimeter' })
const session = new KJAgentToolSession(sdk, drawing)
const model = createKJModelAdapter({
  protocol: 'chat-completions',
  model: selectedModel,
  request: ({ body, signal }) => hostModelGateway(body, signal),
})
const result = await runKJAgentTask({
  session,
  model,
  prompt: '提出一个圆的绘制方案:圆心 (20, 25) 毫米,半径 3 毫米。',
  toolNames: ['cad_read_drawing', 'cad_propose_circles'],
  maxTurns: 8,
  maxToolCalls: 32,
})

selectedModel 与 hostModelGateway 由应用提供。网关返回解析后的非流式模型 JSON,HTTP 失败时抛错。Gemini 适配器使用 REST 请求体,不是 Google SDK 的嵌套 config 参数。密钥、接口白名单和用户权限放在服务端;CAD 包不会搜索密钥、选择地址或自行联网。

兼容接口的输出 token 字段并不完全相同:默认使用 max_tokens,需要时设置 chatTokenParameter: 'max_completion_tokens';其他适配器按各自协议映射 maxOutputTokens。所有工具参数仍由运行时严格校验;Responses 显式使用非 strict 生成模式,不假设各厂商的服务端 Schema 支持完全一致。

通过火山方舟接入豆包

源码中的适配器支持豆包所用的方舟 Chat Completions 协议。模型 ID、HTTPS 请求函数和 ARK_API_KEY 均由可信宿主提供,KJDraw 不读取密钥。官方文档中的基础地址为 https://ark.cn-beijing.volces.com/api/v3,请求路径为 /chat/completions;应选择支持工具调用的模型。适配器在工具结果的下一轮原样保留加密思考块,流式响应中的完整加密块也会保留。

import { createKJDomesticModelAdapter } from '@kanjieteam/kjdraw/domestic-model-profiles'

const model = createKJDomesticModelAdapter({ provider: 'doubao', model: selectedArkModelId, reasoning: { mode: 'enabled' }, request: ({ body, signal }) => callTrustedArkGateway(body, signal), })

上面的模型 ID 和网关函数由你的宿主实现。字段依据方舟 Chat API及深度思考与工具调用说明。本地协议测试已通过,但这些测试不能替代真实方舟账号及具体模型的在线联调。

按任务选择工具

toolNames 是宿主为一次运行设置的可选权限范围。省略时保留全部会话工具;提供时必须是 session.definitions 中非空、不重复的确切名称。未知名称、重复项和空列表在打开模型会话前报错。选中定义保持原始顺序和完整参数约束,包括图档单位。运行器在调用模型前复制选择结果,之后修改传入数组不会扩大权限。

所有协议适配器与自定义桥接收到同一份选中定义。模型请求被省略的工具时,整批调用在任何工具执行前被拒绝,返回 failed 和 KJAGENT_TOOL_NOT_ALLOWED。下一次运行可以重新选择。这不限制宿主直接调用会话,也不代替认证,更不允许模型批准自身提案。需要读取和分页的任务应包含对应工具。缩小 Schema 能减少 JSON 字节,但实际 Token 和任务成功率仍需模型端测量。

处理运行结果

状态宿主应该做什么
awaiting-approval展示 outputs 中的确切修改,用 proposalIds 在审核界面批准或拒绝
responded展示模型回答或澄清问题;这不证明绘图任务已成功
limit-reached检查结果并调整任务或预算,不无限自动重试
cancelled用户取消或运行超时;迟到的模型调用不会再执行
failed处理结构化错误,在服务端检查私有请求日志

一旦得到提案,运行器就停止,不会调用 approve()。经过认证的用户审核后,宿主再调用 session.approve(planId, user.id) 或 session.reject(planId, user.id),并核对结果。模型回复应当作为不可信文字展示,不能直接当作 HTML 渲染。

每次运行都从图纸的当前修订版本开始。应用方案后,把后续需求作为新任务运行,让模型读取更新后的几何。对话持久化与保存策略由应用负责。CAD 工具、方案预览和几何检查见 Agent 工作流。

若要通过包内本地 stdio 服务向 MCP 客户端提供同一套工具注册表,请按 MCP 集成操作。该页面给出了长期客户端配置、真实 JSON-RPC 调用,以及由宿主管理的文件和审批边界。

测量 token 与耗时

result.measurements 保存每个尝试轮次的用量、归一化累计值、传输墙钟耗时和运行器总耗时。计数来自服务端响应字段;缺失或无效值保留 null。缓存与推理 token 按各协议的包含关系处理,避免重复相加。取消后没有收到响应的请求属于用量缺失,complete 仅表示已观测 token 数据完整,不代表绘图完成或完整账单。

const { totals, transportWallMs, runWallMs, complete } = result.measurements
// null 表示无法取得,不能在跑分中当作零。
console.log({ totals, transportWallMs, runWallMs, complete })

适配器还支持 onUsage: usage => hostMetrics.record(usage),用于记录已收到响应的用量,包括被拒绝或截断的回答。观察回调异常不改变绘图行为。取消后的迟到响应仍可送到宿主观察器,但不会改写运行器已返回的测量快照。自定义传输可以使用 /model-usage 的 extractKJModelUsage。这些记录不包含回答文本、密钥、推算 token 或价格。真实模型对比仍需相同任务的重复实验与明确配置的模型服务。

运行包内示例

node node_modules/@kanjieteam/kjdraw/examples/model-agent.mjs

默认离线运行,演示四种消息格式、宿主批准、保存后的图元与撤销,不连接模型。

要连接在线模型,在可信服务端或命令行环境配置 KJDRAW_MODEL_PROTOCOL、KJDRAW_MODEL_NAME、KJDRAW_MODEL_ENDPOINT 与 KJDRAW_MODEL_API_KEY,再加 --live。地址填写完整的可信 REST 接口。示例拒绝重定向和 URL 凭据、限制响应大小,也不会自动应用在线提案。每次运行最多发送四次模型请求和八次工具调用;在线请求可能产生费用。

扩展与验证

实现 KJAgentModel.createConversation({ instructions, tools }),返回 next(input, signal)。每轮返回 text 和 calls;调用包含 id、name、arguments。输入是初始需求或有序工具结果。厂商会话数据留在自己的会话对象中,保留调用与结果的 ID。已有 Agent 运行时也可以直接使用 KJAgentToolSession,自行管理执行循环。

适配器保留 Responses 推理条目、Chat 推理字段、Claude 签名思考块和 Gemini 思考签名,不会将这些字段放进公开回复。截断、拦截、结构损坏或尚未支持的响应会在工具执行前停止;参数校验错误可以反馈给模型,在预算内修正。超时不能强制停止忽略取消信号的远端请求,宿主仍须限制网络资源和费用。

协议资料:OpenAI 工具调用、DeepSeek 工具调用、Claude 工具结果、Gemini GenerateContent。

Guides, Editor API and complete type reference指南、Editor API 与完整类型参考