Skip to Content
卡片 SDKAPI 参考智能体与终端

智能体与终端

列出智能体

需要 agents.read。

import type { AgentInfo } from '@neurosquad/card-sdk' const agents: AgentInfo[] = await card.agents.list() const waiting = agents.filter((a) => a.kind === 'ai' && a.status === 'needs-input') const one = await card.agents.get(agents[0].id) render(waiting.map((a) => a.name), one.model ?? 'default model')

卡片所在工作区中的每个 AI 智能体和终端(其他卡片不是智能体):

字段类型含义
idstring这张卡片在画布上的 id。
namestring用户看到的名称。
harnessstringclaude-code、codex-cli、opencode、qwen-code、shell-bash、shell-powershell、shell-cmd……
kind'ai' 或 'shell'AI 智能体还是终端。
statusAgentStatusworking、needs-input、finished、idle 或 exited。
connectedboolean是否有箭头把它和你的卡片相连。
sessionTitlestring?智能体给自己会话起的标题。
turnStartedAtnumber?当前一轮开始的时间戳(毫秒),在 working 时提供。
lastTurn{ startedAt, endedAt, endedAs }?应用启动以来最近一次结束的一轮:时间戳(毫秒,startedAt 可能为 null),endedAs 为 finished 或 needs-input——用来补上卡片未运行期间错过的轮次。
modelstring?它运行的模型(已知时)。

状态来自与应用其他部分相同的跟踪器——对于 Claude Code,来自它自身的钩子(hook)(对于 OpenCode 和 Kilo Code,来自 NeuroSquad 插件;对于 Hermes Agent,来自它的生命周期 webhook),因此 needs-input(“等待你授权”)和 finished 能被准确区分。

事件

card.agents.onStatus(({ agentId, status }) => render(agentId, status)) card.agents.onTurn(({ agentId, phase, at }) => render(agentId, phase, new Date(at))) card.agents.onChanged((agents) => render(agents.length)) // added, removed or renamed // Only one agent: card.agents.onStatus((e) => render(e.status), agentId)
  • agents.status——状态变化时发送 { agentId, status, at }。
  • agents.turn——{ agentId, phase: 'start' | 'end', at }。提交提示词时一轮开始,智能体完成或需要输入时一轮结束。
  • agents.changed——{ agents },完整的新列表。

有监听器时 SDK 会自动订阅。每个方法都返回一个用于移除监听器的函数。

读取输出

需要 agents.output,并且你的卡片与该智能体或终端之间要有一条箭头。

// The visible screen, as text (up to 500 lines). const screen = await card.agents.readScreen(agentId, 80) // The last reply, from the agent's own session log (Claude Code, OpenCode, Kilo Code, Hermes Agent). null for others. const { text, at } = await card.agents.lastReply(agentId) // Live output: ANSI colours stripped, delivered in chunks about every 100 ms. const stop = card.agents.onOutput([agentId, shellId], ({ agentId: from, text: chunk }) => { if (chunk.includes('FAIL')) render(`${from} printed a failure`) }) stop() // when you no longer need it render(screen, text, at)

对没有箭头相连的智能体调用这些方法会以 NOT_CONNECTED 失败。对未在运行的智能体调用 readScreen 会以 UNAVAILABLE 失败。

向智能体发送提示词

需要 agents.prompt,以及一条连到 AI 智能体的箭头(终端接收的是命令)。

import { isCardSdkError } from '@neurosquad/card-sdk' try { const delivered = await card.agents.prompt(agentId, 'Run the checkout tests and fix what fails.') // 'sent' — submitted now // 'queued' — the agent is working; it goes out when the turn ends // 'inserted'— typed in only (submit: false); the user presses Enter card.ui.toast(delivered === 'queued' ? 'Queued after the current turn' : 'Sent') } catch (error) { if (isCardSdkError(error, 'NOT_CONNECTED')) card.ui.toast('Draw an arrow from me to an agent') else if (isCardSdkError(error, 'BUDGET_PAUSED')) card.ui.toast('The workspace is over its budget') else if (isCardSdkError(error, 'USER_CANCELLED')) card.ui.toast('Not sent') else throw error }

选项——card.agents.prompt(agentId, text, { submit, whenBusy }):

选项默认值含义
submittruefalse 只把文本输入到智能体的输入框而不按回车——由用户检查后发送。结果为 inserted。
whenBusy'queue'智能体正在工作时:queue 放入智能体的提示词队列(queued),send 照样提交(sent),fail 以 BUSY 拒绝。

应用对每条提示词都会:

  • 让它经过与提示词队列和预算相同的路径:工作区超出预算时,以 BUDGET_PAUSED 失败(手动输入的人从不受限——受限的是你的卡片)。
  • 在箭头及其箭头日志中显示,并带上你的卡片名称。
  • 对于处于危险模式的智能体,应用会先在它自己覆盖整个窗口的对话框中显示这条提示词,并等待 Send prompt;用户拒绝则为 USER_CANCELLED; 你的卡片不在屏幕上则为 NOT_VISIBLE。
  • 每张卡片每分钟最多 6 条——与通过智能体 prompt 端口发送的提示词合并计数——每条 ≤ 20 000 个字符。
  • 来自卡片的排队提示词每个智能体最多 10 条,会显示来自哪张卡片;如果箭头、权限、卡片或它的卡片包已不存在,或者智能体被切换到了危险模式,它们会在发出之前被丢弃。

提示词是发给一个能编辑文件、能运行命令的东西的指令。永远不要在未先展示给用户的情况下,把来自网页、文件或其他卡片的文本转发成提示词—— 提示词注入就是这样发生的。文本不是你自己写的时,优先使用 submit: false。

单个智能体的运行

自 NeuroSquad 0.1.264(SDK 1.1)起提供。需要 usage.read 权限,并有箭头连接到一个 AI 智能体——没有箭头的智能体返回 NOT_CONNECTED,shell 返回 INVALID_PARAMS。 每张卡片每分钟最多调用 60 次。请先检查 card.host.supports('agents.usage'):旧版应用会返回 METHOD_NOT_FOUND。

const run = await card.agents.usage(agentId, since /* 毫秒时间戳 */, until /* 可选,默认现在 */)

返回该智能体在时间窗口内的数据——与应用”用量”页面使用的数据相同。智能体工作时你的框架可能被暂停或卸载; 状态历史由应用自己记录,因此用时依然准确。

字段含义
prompts交给智能体的回合数。回答权限请求属于同一回合;没有任何模型请求就结束的回合(状态闪动)不计入。
requests窗口内工具记录的模型请求(API 调用)次数。
inputTokens / outputTokens未缓存的输入;含推理的输出(reasoningTokens 为其中推理部分)。
cacheReadTokens / cacheWriteTokens缓存读写,仅在工具和服务商报告时提供。
totalTokens输入 + 输出 + 缓存读取 + 缓存写入。
elapsedMs从第一个提示到最后一次完成(回合进行中则到现在)。
workingMs智能体实际工作的时间,不含等待用户的时间。
costMicroUsd工具记录的费用,否则按标价,向上取整;价格未知时为 null(包括用户自己服务器上的模型)。
costPartial部分请求没有价格时为 true——费用只包含有价格的请求。
usageReadable应用无法读取其用量日志的工具(Amp、Cursor)为 false:所有词元字段为 null,用时照常统计。
firstPromptAt、lastFinishedAt毫秒时间戳或 null。
model、provider、status、timingComplete、scannedAt这些数字的上下文。应用的状态历史晚于 since 开始时(应用或智能体启动较晚),timingComplete 为 false;scannedAt 是最近一次读取日志的时间。

null 表示未报告:工具日志中没有该数字(有些不记录缓存写入或推理),本地服务器没有发送缓存计数, 或应用根本无法读取该工具的用量日志(Amp、Cursor)。请显示”未报告”,不要显示 0。词元数为精确整数。

时间线上的请求

自 NeuroSquad 0.1.264(SDK 1.2)起提供。权限和箭头要求与 agents.usage 相同;请先检查 card.host.supports('agents.timeline')。

const t = await card.agents.timeline(agentId, since, until /* 可选 */) for (const r of t.requests) draw(r.startedAt ?? r.endedAt, r.endedAt, r.outputTokens, r.tools)
字段含义
requests[]每个模型请求,从旧到新:endedAt(总是有)、startedAt(工具日志记录了发送时间时提供,否则为 null)、词元(null 表示未报告)、tools(模型请求的工具调用)。
requestTimesstart-end——请求有发送时间(画条形);end——只有完成时间(画刻度);none——没有可读日志。
statuses[]智能体状态的连续区间(working、needs-input、finished、idle、exited)。
turns[]提示 → 完成;counted: false 表示没有任何请求的回合(状态抖动)。
truncated窗口内超过 2000 个请求:保留最新的。

终端

需要 terminals.write,以及一条连到终端卡片(bash、PowerShell 或 cmd)的箭头。

// Run a command and wait for it to finish. const result = await card.terminals.run(shellId, 'npm test -- --reporter=dot', { timeoutMs: 120_000 }) if (result.timedOut) render('still running after 2 minutes') else render(result.exitCode === 0 ? 'passed' : `failed with ${result.exitCode}`, result.output) // Or just type into it (and press Enter). await card.terminals.write(shellId, 'git status', { submit: true })
run(agentId, command, { timeoutMs? })write(agentId, text, { submit? })
作用运行一条命令并等待提示符返回输入文本;submit: true 会在之后按回车
返回{ exitCode, output, truncated, timedOut }无
限制超时 1–120 秒(默认 120),输出 ≤ 64 KB;每张卡片每分钟 30 条命令,与终端的 command 端口共享每分钟 60 次

在 cmd 中 exitCode 为 null,因为 cmd 不报告退出码。用户能在终端本身和箭头上看到每条命令。 命令不受智能体预算限制——终端不是 AI 智能体——但它们以用户的完整权限运行:参见安全检查清单。