refactor: apply repository naming contract
Apply the accepted pre-release package, service, type, directory, and role renames as one repository-wide change.
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/interaction/tool-ask-user/README.md
|
||||
README.md: bb0af4286d6d0626596202d57e55fd818b92f44b
|
||||
README.zh.md: c1424bb3cc9c7805f1b5112c382d6f75d7a3380d
|
||||
README.md: bf2ba369fca36c462c6155ed2354ab3d0e930dd0
|
||||
README.zh.md: 671bea0132093b890de4ce27095fa60dac396276
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Model-facing `ask_user_question` tool over `ctx.userInteraction`. It lets the model ask the human a concise question when it needs confirmation, a choice, or missing information before continuing.
|
||||
Model-facing `ask_user_question` tool over `ctx.userQuestions`. It lets the model ask the human a concise question when it needs confirmation, a choice, or missing information before continuing.
|
||||
|
||||
## Tool
|
||||
|
||||
@@ -15,11 +15,11 @@ Model-facing `ask_user_question` tool over `ctx.userInteraction`. It lets the mo
|
||||
- `options` — optional choices with `label` and `description`. If recommending a choice, put it first and append `(Recommended)` to that label.
|
||||
- `multi_select` — whether that question may return more than one selected option.
|
||||
|
||||
The tool calls `ctx.userInteraction.ask()` and returns canonical `{ answers: [{ id, selected, custom? }] }`. `selected` contains option labels; `custom` carries a free-form answer, supplementing `selected` for a multi-select question and overriding it for a single-select question. The Native renderer preserves the compact JSON text shape `{ "answers": [{ "id": "...", "selected": ["..."], "custom": "..." }] }`.
|
||||
The tool calls `ctx.userQuestions.ask()` and returns canonical `{ answers: [{ id, selected, custom? }] }`. `selected` contains option labels; `custom` carries a free-form answer, supplementing `selected` for a multi-select question and overriding it for a single-select question. The Native renderer preserves the compact JSON text shape `{ "answers": [{ "id": "...", "selected": ["..."], "custom": "..." }] }`.
|
||||
|
||||
## Role
|
||||
|
||||
This is the Consumer package for the user-interaction seam. It does not render UI and does not know how input is collected; it only translates model arguments into `AskUserQuestionRequest` and returns the human answer to the agent loop.
|
||||
This is the Consumer package for the user-questions seam. It does not render UI and does not know how input is collected; it only translates model arguments into `AskUserQuestionRequest` and returns the human answer to the agent loop.
|
||||
|
||||
## Model Experience
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
模型侧 `ask_user_question` 工具,基于 `ctx.userInteraction` 实现。当模型需要确认、选择结果或缺失的信息才能继续时,它可以借此向用户提出简明问题。
|
||||
模型侧 `ask_user_question` 工具,基于 `ctx.userQuestions` 实现。当模型需要确认、选择结果或缺失的信息才能继续时,它可以借此向用户提出简明问题。
|
||||
|
||||
## 工具
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
- `options`:可选选项,包含 `label` 和 `description`。如需推荐某个选项,请将其置于首位,并在该标签末尾追加 `(Recommended)`。
|
||||
- `multi_select`:该问题是否可以返回多个选中的选项。
|
||||
|
||||
工具调用 `ctx.userInteraction.ask()`,并返回规范的 `{ answers: [{ id, selected, custom? }] }`。`selected` 包含选项标签;`custom` 携带自由填写的回答,对于多选题会补充 `selected`,对于单选题则会覆盖它。Native 渲染器会保留紧凑的 JSON 文本形式 `{ "answers": [{ "id": "...", "selected": ["..."], "custom": "..." }] }`。
|
||||
工具调用 `ctx.userQuestions.ask()`,并返回规范的 `{ answers: [{ id, selected, custom? }] }`。`selected` 包含选项标签;`custom` 携带自由填写的回答,对于多选题会补充 `selected`,对于单选题则会覆盖它。Native 渲染器会保留紧凑的 JSON 文本形式 `{ "answers": [{ "id": "...", "selected": ["..."], "custom": "..." }] }`。
|
||||
|
||||
## 职责
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@deepseek-ai/dsh-tool-ask-user",
|
||||
"description": "Model-facing ask_user_question tool over the ctx.userInteraction seam",
|
||||
"description": "Model-facing ask_user_question tool over the ctx.userQuestions seam",
|
||||
"version": "0.0.1-rc.2",
|
||||
"publishConfig": {
|
||||
"access": "restricted"
|
||||
@@ -35,7 +35,7 @@
|
||||
"@deepseek-ai/dsh-agent": "workspace:^",
|
||||
"@deepseek-ai/dsh-invariants": "workspace:^",
|
||||
"@deepseek-ai/dsh-tools": "workspace:^",
|
||||
"@deepseek-ai/dsh-user-interaction": "workspace:^",
|
||||
"@deepseek-ai/dsh-user-questions": "workspace:^",
|
||||
"@deepseek-ai/cordis": "workspace:^"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -44,7 +44,7 @@
|
||||
"@deepseek-ai/dsh-llm": "workspace:^",
|
||||
"@deepseek-ai/dsh-system-prompt": "workspace:^",
|
||||
"@deepseek-ai/dsh-tools": "workspace:^",
|
||||
"@deepseek-ai/dsh-user-interaction": "workspace:^",
|
||||
"@deepseek-ai/dsh-user-questions": "workspace:^",
|
||||
"@deepseek-ai/cordis": "workspace:^"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Model-facing Consumer of the `ctx.userInteraction` capability seam.
|
||||
* Model-facing Consumer of the `ctx.userQuestions` capability seam.
|
||||
* The tool pauses until a UI provider returns a human answer, then feeds that
|
||||
* answer back into the agent loop as an ordinary tool result.
|
||||
*
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
import type { Context } from '@deepseek-ai/cordis'
|
||||
import { defineTool } from '@deepseek-ai/dsh-tools'
|
||||
import '@deepseek-ai/dsh-user-interaction'
|
||||
import '@deepseek-ai/dsh-user-questions'
|
||||
|
||||
export const name = 'tool-ask-user'
|
||||
export const inject = ['tools', 'userInteraction']
|
||||
export const inject = ['tools', 'userQuestions']
|
||||
|
||||
const description = 'Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. '
|
||||
+ 'Send one or more questions, each with a stable id that will be echoed in the answer.'
|
||||
@@ -78,7 +78,7 @@ export function apply(ctx: Context): void {
|
||||
render: (_args, value) => [{ type: 'text', text: JSON.stringify(value) }],
|
||||
},
|
||||
async execute(args, exec) {
|
||||
const result = await ctx.userInteraction.ask({
|
||||
const result = await ctx.userQuestions.ask({
|
||||
questions: args.questions.map(question => ({
|
||||
id: question.id,
|
||||
question: question.question,
|
||||
|
||||
@@ -3,8 +3,8 @@ import { Context } from '@deepseek-ai/cordis'
|
||||
import { CallId } from '@deepseek-ai/dsh-llm'
|
||||
import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent'
|
||||
import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
|
||||
import ToolRegistry from '@deepseek-ai/dsh-tools'
|
||||
import UserInteractionService, { type AskUserQuestionRequest } from '@deepseek-ai/dsh-user-interaction'
|
||||
import ToolRuntime from '@deepseek-ai/dsh-tools'
|
||||
import UserQuestionService, { type AskUserQuestionRequest } from '@deepseek-ai/dsh-user-questions'
|
||||
import * as toolAskUser from '@deepseek-ai/dsh-tool-ask-user'
|
||||
|
||||
const testToolSignal = new AbortController().signal
|
||||
@@ -29,8 +29,8 @@ async function setup() {
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(AgentRegistry)
|
||||
await ctx.plugin(SystemPrompt)
|
||||
await ctx.plugin(ToolRegistry)
|
||||
await ctx.plugin(UserInteractionService)
|
||||
await ctx.plugin(ToolRuntime)
|
||||
await ctx.plugin(UserQuestionService)
|
||||
await ctx.plugin(toolAskUser)
|
||||
return ctx
|
||||
}
|
||||
@@ -75,10 +75,10 @@ describe('ask_user_question tool', () => {
|
||||
expect(parameters.properties.questions.items.properties.options.items.properties).not.toHaveProperty('preview')
|
||||
})
|
||||
|
||||
it('asks the registered user-interaction provider and projects structured answers to text', async () => {
|
||||
it('asks the registered user-questions provider and projects structured answers to text', async () => {
|
||||
const ctx = await setup()
|
||||
const seen: AskUserQuestionRequest[] = []
|
||||
ctx.userInteraction.registerProvider({
|
||||
ctx.userQuestions.registerProvider({
|
||||
async ask(request) {
|
||||
seen.push(request)
|
||||
return { answers: [{ id: 'pkg', selected: ['pnpm'] }] }
|
||||
@@ -114,7 +114,7 @@ describe('ask_user_question tool', () => {
|
||||
it('passes recommended option labels through without adding schema fields', async () => {
|
||||
const ctx = await setup()
|
||||
const seen: AskUserQuestionRequest[] = []
|
||||
ctx.userInteraction.registerProvider({
|
||||
ctx.userQuestions.registerProvider({
|
||||
async ask(request) {
|
||||
seen.push(request)
|
||||
return { answers: [{ id: 'pkg', selected: ['pnpm (Recommended)'] }] }
|
||||
@@ -145,7 +145,7 @@ describe('ask_user_question tool', () => {
|
||||
|
||||
it('projects custom answers and multi-select choices', async () => {
|
||||
const ctx = await setup()
|
||||
ctx.userInteraction.registerProvider({
|
||||
ctx.userQuestions.registerProvider({
|
||||
async ask() {
|
||||
return {
|
||||
answers: [
|
||||
@@ -195,10 +195,10 @@ describe('ask_user_question tool', () => {
|
||||
}])
|
||||
})
|
||||
|
||||
it('passes the tool abort signal to the user-interaction request', async () => {
|
||||
it('passes the tool abort signal to the user-questions request', async () => {
|
||||
const ctx = await setup()
|
||||
const seen: AskUserQuestionRequest[] = []
|
||||
ctx.userInteraction.registerProvider({
|
||||
ctx.userQuestions.registerProvider({
|
||||
async ask(request) {
|
||||
seen.push(request)
|
||||
return { answers: [{ id: 'continue', selected: ['ok'] }] }
|
||||
@@ -216,10 +216,10 @@ describe('ask_user_question tool', () => {
|
||||
expect(seen[0]?.signal).toBe(controller.signal)
|
||||
})
|
||||
|
||||
it('passes optional header and a resumed runtime root through to the user-interaction request', async () => {
|
||||
it('passes optional header and a resumed runtime root through to the user-questions request', async () => {
|
||||
const ctx = await setup()
|
||||
const seen: AskUserQuestionRequest[] = []
|
||||
ctx.userInteraction.registerProvider({
|
||||
ctx.userQuestions.registerProvider({
|
||||
async ask(request) {
|
||||
seen.push(request)
|
||||
return { answers: [{ id: 'continue', selected: ['ok'] }] }
|
||||
@@ -240,7 +240,7 @@ describe('ask_user_question tool', () => {
|
||||
expect(seen[0]).toMatchObject({ questions: [{ id: 'continue', header: 'Confirm', question: 'Continue?' }], agent })
|
||||
})
|
||||
|
||||
it('returns structured user-interaction errors through tool execution', async () => {
|
||||
it('returns structured user-questions errors through tool execution', async () => {
|
||||
const ctx = await setup()
|
||||
|
||||
const result = await ctx.tools.execute({
|
||||
@@ -252,14 +252,14 @@ describe('ask_user_question tool', () => {
|
||||
|
||||
expect(result).toMatchObject({
|
||||
isError: true,
|
||||
error: { info: { name: 'UserInteractionError', code: 'NO_PROVIDER' } },
|
||||
error: { info: { name: 'UserQuestionError', code: 'NO_PROVIDER' } },
|
||||
})
|
||||
})
|
||||
|
||||
it('rejects a live runtime-owned agent with a structured DELEGATED_CALLER error', async () => {
|
||||
const ctx = await setup()
|
||||
const seen: AskUserQuestionRequest[] = []
|
||||
ctx.userInteraction.registerProvider({
|
||||
ctx.userQuestions.registerProvider({
|
||||
async ask(request) {
|
||||
seen.push(request)
|
||||
return { answers: [{ id: 'continue', selected: ['ok'] }] }
|
||||
@@ -280,7 +280,7 @@ describe('ask_user_question tool', () => {
|
||||
|
||||
expect(result).toMatchObject({
|
||||
isError: true,
|
||||
error: { info: { name: 'UserInteractionError', code: 'DELEGATED_CALLER' } },
|
||||
error: { info: { name: 'UserQuestionError', code: 'DELEGATED_CALLER' } },
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: "Error: human interaction is unavailable while the calling agent is owned by another live agent; include the unresolved question or decision in the child agent's final result",
|
||||
@@ -301,15 +301,15 @@ describe('ask_user_question tool', () => {
|
||||
|
||||
expect(result).toMatchObject({
|
||||
isError: true,
|
||||
error: { info: { name: 'UserInteractionError', code: 'EMPTY_QUESTIONS' } },
|
||||
error: { info: { name: 'UserQuestionError', code: 'EMPTY_QUESTIONS' } },
|
||||
})
|
||||
})
|
||||
|
||||
it('unregisters the tool when its plugin fiber is disposed', async () => {
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SystemPrompt)
|
||||
await ctx.plugin(ToolRegistry)
|
||||
await ctx.plugin(UserInteractionService)
|
||||
await ctx.plugin(ToolRuntime)
|
||||
await ctx.plugin(UserQuestionService)
|
||||
const fiber = await ctx.plugin(toolAskUser)
|
||||
expect(ctx.tools.get('ask_user_question')).toBeDefined()
|
||||
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
"path": "../../core/tools"
|
||||
},
|
||||
{
|
||||
"path": "../user-interaction"
|
||||
"path": "../user-questions"
|
||||
},
|
||||
{
|
||||
"path": "../../support/invariants"
|
||||
"path": "../../runtime-diagnostics/invariants"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user