Skip to main content
输入与输出

多轮对话

一次性、无状态查询用 query() 即可,见 快速开始。要在同一会话里发多条用户消息,两个 SDK 的方式不同:
  • TypeScript:给 query() 传入一个按顺序产出用户消息的异步消息流,输入流结束后会话自动关闭。
  • Python:使用 QoderSDKClient——它维护长连接,可以根据模型回复决定下一句。

多消息会话

import { qodercliAuth, query, type SDKUserMessage } from '@qodercn-ai/qodercn-agent-sdk';

async function* messages(): AsyncGenerator<SDKUserMessage> {
  yield {
    type: 'user',
    message: { role: 'user', content: [{ type: 'text', text: 'Analyze this codebase for security issues.' }] },
    parent_tool_use_id: null,
  };

  // Wait for any external condition before sending the next message.
  await new Promise((resolve) => setTimeout(resolve, 2000));

  yield {
    type: 'user',
    message: { role: 'user', content: [{ type: 'text', text: 'Now write a brief report.' }] },
    parent_tool_use_id: null,
  };
}

for await (const msg of query({
  prompt: messages(),
  options: {
    auth: qodercliAuth(),
    allowedTools: ['Read', 'Grep'],
  },
})) {
  if (msg.type === 'result' && msg.subtype === 'success') {
    console.log(msg.result);
  }
}
通常,发送用户消息后,模型会开始回复。在回复结束前发送的新消息,会在 priority 指定的时机处理。TypeScript 中输入消息流结束后会话自动关闭,消息字段定义见 SDKUserMessage;Python 中每次调用 client.query(...) 追加一轮输入,再用 client.receive_response() 消费到本轮回复结束。

运行中插话

模型回复期间,仍可继续向同一会话发送新消息:
yield {
  type: 'user',
  message: { role: 'user', content: [{ type: 'text', text: 'Stop the current direction and analyze only the failing tests.' }] },
  parent_tool_use_id: null,
  priority: 'now',
};
priority 决定消息何时交给会话:
行为
now停止当前回复,立即处理这条消息
next默认值;在下一个合适的时机处理
later等当前回复结束后处理
相同优先级的消息按发送顺序处理。prioritynow 适合立即改变当前方向;如果只想停止当前回复、不发送新消息,应使用 中断当前回复

添加上下文但不触发回复

设置 shouldQuery: false(TypeScript)/ should_query=False(Python)会把消息加入对话,但不会仅凭这条消息触发回复。消息的处理时机仍由 priority 决定。
yield {
  type: 'user',
  message: { role: 'user', content: [{ type: 'text', text: 'All subsequent suggestions must be compatible with Python 3.10.' }] },
  parent_tool_use_id: null,
  shouldQuery: false,
};

中断当前回复

调用 interrupt() 可以停止当前回复,但不会关闭会话,之后仍可继续对话。TypeScript 中在 query() 返回的对象上调用;Python 中只有 QoderSDKClient 提供运行时中断能力,一次性 query() 迭代器不提供。
import { qodercliAuth, query } from '@qodercn-ai/qodercn-agent-sdk';

const q = query({
  prompt: 'Inspect all files in the repository.',
  options: { auth: qodercliAuth() },
});

const interruptTimer = setTimeout(() => {
  void q.interrupt().catch(console.error);
}, 5_000);

try {
  for await (const msg of q) {
    console.dir(msg, { depth: null });
  }
} finally {
  clearTimeout(interruptTimer);
}
interrupt() 不会清空排队消息,之后仍可发送下一轮输入。如果某条排队消息不能继续执行,请使用取消排队消息。结束整个会话的方式见 管理会话生命周期

取消排队消息

给需要跟踪的消息设置会话内唯一的 UUID(TypeScript 为消息上的 uuid 字段,Python 为 message_uuid 参数),再调用取消方法,取消尚未开始执行的消息:
const cancelled = await q.cancelAsyncMessage(uuid);
取消成功返回 true;消息不存在或已无法取消时返回 false。未设置 UUID 的消息无法通过该方法取消。不要在同一会话内复用 UUID。

管理会话生命周期

  • TypeScript:单条字符串输入处理完成或输入消息流结束后,SDK 会自动关闭会话;提前结束可以用 AbortController,也可以直接调用 q.close()
  • PythonQoderSDKClient 的连接生命周期由调用方掌握,推荐用 async with 自动管理,也可以手动 connect() / disconnect()

绑定代码块的自动收尾

适合会话生命周期跟某个函数 / 代码块绑定的场景。TypeScript 把 close() 放在 finally 中确保相关资源关闭完成;Python 在 async with 块退出时自动断开连接:
import { qodercliAuth, query } from '@qodercn-ai/qodercn-agent-sdk';

const q = query({
  prompt: 'Inspect all files in the repository.',
  options: { auth: qodercliAuth() },
});

try {
  for await (const msg of q) {
    console.dir(msg, { depth: null });
  }
} finally {
  await q.close();
}

由外部条件触发结束

适合需要从外部条件(超时、用户取消、应用退出等)触发关闭的场景。TypeScript 创建 AbortController 并通过 options.abortController 传入,条件满足时调用 abort() 关闭整个会话并结束消息迭代;Python 手动持有 client,在 finally 中调用 disconnect()
import { qodercliAuth, query } from '@qodercn-ai/qodercn-agent-sdk';

const abortController = new AbortController();
const q = query({
  prompt: 'Inspect all files in the repository.',
  options: { auth: qodercliAuth(), abortController },
});

const taskTimeout = setTimeout(() => abortController.abort(), 5_000);
try {
  for await (const msg of q) {
    console.dir(msg, { depth: null });
  }
} finally {
  clearTimeout(taskTimeout);
}
会话关闭后不能继续发送消息。