Skip to content

Context

Handler 接收的上下文对象。

结构

typescript
interface Context {
  readonly streamId: string
  readonly stream: BidirectionalStream
  readonly signal: AbortSignal
  readonly metadata: grpc.Metadata
  readonly message: Message

  getAgentCard: () => AgentCard
  getMetadata: <T>(key: string) => T | undefined
}

常用操作

发送消息

typescript
ctx.stream.send({
  type: 'progress',
  text: '处理中...',
  data: { percent: 50 }
})

读取 Metadata

typescript
const userId = ctx.getMetadata<string>('x-user-id')
const traceId = ctx.getMetadata<string>('x-trace-id')

检查取消

typescript
if (ctx.signal.aborted) {
  throw new Error('Cancelled')
}

// 传递给下游
await fetch(url, { signal: ctx.signal })

获取 Agent 信息

typescript
const card = ctx.getAgentCard()
console.log(`Running on ${card.name}`)

等待用户回答

typescript
ctx.stream.send({
  type: 'question',
  text: '确认?',
  data: { questionId: 'confirm' }
})

for await (const msg of ctx.stream) {
  if (msg.type === 'answer' && msg.data.questionId === 'confirm') {
    const answer = msg.data.answer
    break
  }
}

完整示例

typescript
const skill = defineSkill('task', async (params, ctx) => {
  // 读取 metadata
  const userId = ctx.getMetadata<string>('x-user-id')

  // 发送进度
  ctx.stream.send({ type: 'progress', text: '开始处理...' })

  // 检查取消
  if (ctx.signal.aborted) throw new Error('Cancelled')

  // 调用其他 Agent
  const client = createAgentClient({ agentId: 'chat-agent', address: 'a2a://localhost:50054' })
  const stream = await client.call('chat', params, {
    signal: ctx.signal,
    metadata: { 'x-trace-id': ctx.getMetadata('x-trace-id') }
  })

  // 转发响应
  for await (const msg of stream) {
    ctx.stream.send(msg)
    if (msg.type === 'done') return msg.data
  }
})

MIT Licensed