@agimon-ai/doompi-user-feedback 0.0.1-alpha.1 → 0.0.1-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -4
- package/dist/adapters/doom/voiceQuestionHandoff.cjs +2 -2
- package/dist/adapters/doom/voiceQuestionHandoff.cjs.map +1 -1
- package/dist/adapters/doom/voiceQuestionHandoff.d.cts +32 -0
- package/dist/adapters/doom/voiceQuestionHandoff.d.cts.map +1 -0
- package/dist/adapters/doom/voiceQuestionHandoff.d.mts +32 -0
- package/dist/adapters/doom/voiceQuestionHandoff.d.mts.map +1 -0
- package/dist/adapters/doom/voiceQuestionHandoff.mjs +2 -2
- package/dist/adapters/doom/voiceQuestionHandoff.mjs.map +1 -1
- package/dist/extensions/pi.cjs +1 -1
- package/dist/extensions/pi.cjs.map +1 -1
- package/dist/extensions/pi.d.cts.map +1 -1
- package/dist/extensions/pi.d.mts.map +1 -1
- package/dist/extensions/pi.mjs +1 -1
- package/dist/extensions/pi.mjs.map +1 -1
- package/dist/schemas/questionnaire.d.cts +18 -0
- package/dist/schemas/questionnaire.d.cts.map +1 -0
- package/dist/schemas/questionnaire.d.mts +18 -0
- package/dist/schemas/questionnaire.d.mts.map +1 -0
- package/dist/types/questionnaire.d.cts +31 -0
- package/dist/types/questionnaire.d.cts.map +1 -0
- package/dist/types/questionnaire.d.mts +31 -0
- package/dist/types/questionnaire.d.mts.map +1 -0
- package/dist/voiceQuestionHandoff.cjs +1 -0
- package/dist/voiceQuestionHandoff.d.cts +4 -0
- package/dist/voiceQuestionHandoff.d.mts +4 -0
- package/dist/voiceQuestionHandoff.mjs +1 -0
- package/package.json +19 -7
package/README.md
CHANGED
|
@@ -1,10 +1,95 @@
|
|
|
1
1
|
# @agimon-ai/doompi-user-feedback
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Structured, blocking user questions for Pi, with an autonomous-Voice handoff.
|
|
4
4
|
|
|
5
|
-
The
|
|
5
|
+
The `ask_user_question` tool presents concrete options instead of asking the model to continue on a guess.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
> **Alpha:** tool and Voice-handoff contracts may change between releases.
|
|
8
|
+
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
- Node.js 22.19.0 or newer
|
|
12
|
+
- Pi 0.84.2 and Pi TUI 0.84.2
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
Add the package to a DoomPi layer:
|
|
17
|
+
|
|
18
|
+
```yaml
|
|
19
|
+
layers:
|
|
20
|
+
feedback:
|
|
21
|
+
packages: ['@agimon-ai/doompi-user-feedback']
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
For standalone Pi:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pi install npm:@agimon-ai/doompi-user-feedback
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Ask a question
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"questions": [
|
|
35
|
+
{
|
|
36
|
+
"header": "Storage",
|
|
37
|
+
"question": "Where should session results be stored?",
|
|
38
|
+
"options": [
|
|
39
|
+
{
|
|
40
|
+
"label": "Project files",
|
|
41
|
+
"description": "Easy to inspect and commit, but visible in the repository."
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"label": "User state",
|
|
45
|
+
"description": "Keeps generated state outside the repository."
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"multiSelect": false
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
A call accepts 1–4 questions. Each question requires 2–4 options. Headers are at most 16 characters; option labels are at most 60 characters. Use `multiSelect: true` when several choices are valid. An option can include a Markdown `preview` for meaningful visual comparison.
|
|
55
|
+
|
|
56
|
+
The tool result contains readable answer text plus structured `details.answers`; cancellation sets `cancelled: true`. Pressing Escape declines the questionnaire. Do not add an `Other` option because the UI supplies a custom-text row.
|
|
57
|
+
|
|
58
|
+
## UI, RPC, and headless behavior
|
|
59
|
+
|
|
60
|
+
The tool requires an interactive UI. It uses the TUI questionnaire when available and can use Pi's dialog/RPC UI bridge. A truly headless context returns a structured `no_ui` cancellation rather than waiting forever.
|
|
61
|
+
|
|
62
|
+
Questionnaires are coordinated one at a time. Cancellation, session replacement, or shutdown aborts the active prompt and settles queued work.
|
|
63
|
+
|
|
64
|
+
## Autonomous Voice handoff
|
|
65
|
+
|
|
66
|
+
When autonomous Voice mode is active, the extension formats the questions as plain text, requests narration, and returns `terminate: true`. The current turn ends while waiting; the next spoken answer arrives as a normal user message rather than a synthetic questionnaire selection.
|
|
67
|
+
|
|
68
|
+
Reusable integrations can create a session-scoped handoff:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import { createVoiceQuestionHandoff } from '@agimon-ai/doompi-user-feedback/voice-question-handoff';
|
|
72
|
+
import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
|
|
73
|
+
|
|
74
|
+
export function installVoiceHandoff(pi: ExtensionAPI, sessionId: string): () => void {
|
|
75
|
+
const handoff = createVoiceQuestionHandoff({
|
|
76
|
+
bus: pi.events,
|
|
77
|
+
source: '@example/review-extension',
|
|
78
|
+
sessionId,
|
|
79
|
+
});
|
|
80
|
+
return () => handoff.dispose();
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Always dispose the handle during shutdown.
|
|
85
|
+
|
|
86
|
+
## Public API
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import { registerUserFeedbackExtension } from '@agimon-ai/doompi-user-feedback';
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Event constants are available through `/events`; the Pi adapter is `/extensions/pi`.
|
|
8
93
|
|
|
9
94
|
## Development
|
|
10
95
|
|
|
@@ -15,4 +100,6 @@ pnpm test
|
|
|
15
100
|
pnpm lint
|
|
16
101
|
```
|
|
17
102
|
|
|
18
|
-
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
MIT
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const e=`The questions were spoken through autonomous voice. Stop now and wait for the user's next message; it will arrive as an ordinary user message.`;function
|
|
1
|
+
const e=require("../../services/voiceQuestionNarration.cjs");let t=require("@agimon-ai/doompi-extension-contracts/mode"),n=require("@agimon-ai/doompi-extension-contracts/narration"),r=require("@agimon-ai/doompi-extension-contracts/protocol");const i=`The questions were spoken through autonomous voice. Stop now and wait for the user's next message; it will arrive as an ordinary user message.`;function a(e){return e.descriptor.source===`@agimon-ai/doompi-voice`&&e.descriptor.id===`voice-auto`&&e.state.activation===`active`}function o(e){let t=e.questions.length>1;return e.questions.map((e,n)=>[`${t?`${n+1}. `:``}${e.question}${e.multiSelect?` (Select all that apply.)`:``}`,...e.options.map((e,t)=>` ${t+1}. ${e.label}`),` Type something.`].join(`
|
|
2
2
|
`)).join(`
|
|
3
3
|
|
|
4
|
-
`)}var
|
|
4
|
+
`)}var s=class{modes;narration;buildNarration;constructor(e,t,n){this.modes=e,this.narration=t,this.buildNarration=n}handoff(e){if(this.modes.list().some(a))return this.narration.narrate(this.buildNarration(e)),{answers:[],cancelled:!1,delivery:`voice`,awaitingResponse:!0,voicePrompt:o(e)}}};function c(i){let a=(0,t.createMinorModeCatalogClient)(),o=a.bind((0,r.createProtocolRuntime)(i)),c=new s(a,(0,n.createNarrationRequester)(i),e.buildVoiceQuestionNarration),l=!1;return{handoff(e){return l?void 0:c.handoff(e)},dispose(){l||(l=!0,o(),a.dispose())}}}function l(e){let t=e.voicePrompt?.trim();return{content:[{type:`text`,text:t?`${t}\n\n${i}`:i}],details:e,terminate:!0}}exports.DOOM_VOICE_AUTO_MODE_ID=`voice-auto`,exports.DOOM_VOICE_SOURCE=`@agimon-ai/doompi-voice`,exports.VOICE_WAIT_MESSAGE=i,exports.VoiceQuestionHandoff=s,exports.buildVoiceToolResult=l,exports.createVoiceQuestionHandoff=c,exports.formatVoiceQuestionPrompt=o;
|
|
5
5
|
//# sourceMappingURL=voiceQuestionHandoff.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voiceQuestionHandoff.cjs","names":[],"sources":["../../../src/adapters/doom/voiceQuestionHandoff.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"voiceQuestionHandoff.cjs","names":["createMinorModeCatalogClient","createProtocolRuntime","createNarrationRequester","buildVoiceQuestionNarration"],"sources":["../../../src/adapters/doom/voiceQuestionHandoff.ts"],"sourcesContent":["import {\n createMinorModeCatalogClient,\n type MinorModeCatalogClient,\n type MinorModeRecord,\n} from '@agimon-ai/doompi-extension-contracts/mode';\nimport { createNarrationRequester, type NarrationRequester } from '@agimon-ai/doompi-extension-contracts/narration';\nimport { createProtocolRuntime, type ProtocolRuntimeOptions } from '@agimon-ai/doompi-extension-contracts/protocol';\nimport type { QuestionParams } from '../../schemas/questionnaire.js';\nimport { buildVoiceQuestionNarration } from '../../services/voiceQuestionNarration.js';\nimport type { QuestionnaireResult, ToolTextResult } from '../../types/questionnaire.js';\n\nexport const DOOM_VOICE_SOURCE = '@agimon-ai/doompi-voice';\nexport const DOOM_VOICE_AUTO_MODE_ID = 'voice-auto';\nexport const VOICE_WAIT_MESSAGE =\n \"The questions were spoken through autonomous voice. Stop now and wait for the user's next message; it will arrive as an ordinary user message.\";\n\nfunction isAutonomousVoice(record: MinorModeRecord): boolean {\n return (\n record.descriptor.source === DOOM_VOICE_SOURCE &&\n record.descriptor.id === DOOM_VOICE_AUTO_MODE_ID &&\n record.state.activation === 'active'\n );\n}\n\nexport function formatVoiceQuestionPrompt(params: QuestionParams): string {\n const numberQuestions = params.questions.length > 1;\n return params.questions\n .map((question, questionIndex) => {\n const heading = `${numberQuestions ? `${questionIndex + 1}. ` : ''}${question.question}${question.multiSelect ? ' (Select all that apply.)' : ''}`;\n const options = question.options.map((option, optionIndex) => ` ${optionIndex + 1}. ${option.label}`);\n return [heading, ...options, ' Type something.'].join('\\n');\n })\n .join('\\n\\n');\n}\n\nexport class VoiceQuestionHandoff {\n constructor(\n private readonly modes: Pick<MinorModeCatalogClient, 'list'>,\n private readonly narration: NarrationRequester,\n private readonly buildNarration: (params: QuestionParams) => string,\n ) {}\n\n handoff(params: QuestionParams): QuestionnaireResult | undefined {\n if (!this.modes.list().some(isAutonomousVoice)) return undefined;\n this.narration.narrate(this.buildNarration(params));\n return {\n answers: [],\n cancelled: false,\n delivery: 'voice',\n awaitingResponse: true,\n voicePrompt: formatVoiceQuestionPrompt(params),\n };\n }\n}\n\nexport interface VoiceQuestionHandoffHandle {\n handoff(params: QuestionParams): QuestionnaireResult | undefined;\n dispose(): void;\n}\n\n/**\n * Bind one session-scoped autonomous-voice handoff.\n *\n * The returned handle owns the external catalog subscription and must be\n * disposed when its session is replaced or shut down.\n */\nexport function createVoiceQuestionHandoff(options: ProtocolRuntimeOptions): VoiceQuestionHandoffHandle {\n const modes = createMinorModeCatalogClient();\n const disposeBinding = modes.bind(createProtocolRuntime(options));\n const handoff = new VoiceQuestionHandoff(modes, createNarrationRequester(options), buildVoiceQuestionNarration);\n let disposed = false;\n\n return {\n handoff(params) {\n return disposed ? undefined : handoff.handoff(params);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n disposeBinding();\n modes.dispose();\n },\n };\n}\n\nexport function buildVoiceToolResult(details: QuestionnaireResult): ToolTextResult {\n const prompt = details.voicePrompt?.trim();\n return {\n content: [{ type: 'text', text: prompt ? `${prompt}\\n\\n${VOICE_WAIT_MESSAGE}` : VOICE_WAIT_MESSAGE }],\n details,\n terminate: true,\n };\n}\n"],"mappings":"kPAWA,MAEa,EACX,iJAEF,SAAS,EAAkB,EAAkC,CAC3D,OACE,EAAO,WAAW,SAAA,2BAClB,EAAO,WAAW,KAAA,cAClB,EAAO,MAAM,aAAe,QAEhC,CAEA,SAAgB,EAA0B,EAAgC,CACxE,IAAM,EAAkB,EAAO,UAAU,OAAS,EAClD,OAAO,EAAO,UACX,KAAK,EAAU,IAGP,CAAC,GAFW,EAAkB,GAAG,EAAgB,EAAE,IAAM,KAAK,EAAS,WAAW,EAAS,YAAc,4BAA8B,KAE7H,GADD,EAAS,QAAQ,KAAK,EAAQ,IAAgB,KAAK,EAAc,EAAE,IAAI,EAAO,OACpE,EAAG,mBAAmB,CAAC,CAAC,KAAK;CAAI,CAC5D,CAAC,CACD,KAAK;;CAAM,CAChB,CAEA,IAAa,EAAb,KAAkC,CAEb,MACA,UACA,eAHnB,YACE,EACA,EACA,EACA,CAHiB,KAAA,MAAA,EACA,KAAA,UAAA,EACA,KAAA,eAAA,CAChB,CAEH,QAAQ,EAAyD,CAC1D,QAAK,MAAM,KAAK,CAAC,CAAC,KAAK,CAAiB,EAE7C,OADA,KAAK,UAAU,QAAQ,KAAK,eAAe,CAAM,CAAC,EAC3C,CACL,QAAS,CAAC,EACV,UAAW,GACX,SAAU,QACV,iBAAkB,GAClB,YAAa,EAA0B,CAAM,CAC/C,CACF,CACF,EAaA,SAAgB,EAA2B,EAA6D,CACtG,IAAM,GAAA,EAAQA,EAAAA,6BAAAA,CAA6B,EACrC,EAAiB,EAAM,MAAA,EAAKC,EAAAA,sBAAAA,CAAsB,CAAO,CAAC,EAC1D,EAAU,IAAI,EAAqB,GAAA,EAAOC,EAAAA,yBAAAA,CAAyB,CAAO,EAAGC,EAAAA,2BAA2B,EAC1G,EAAW,GAEf,MAAO,CACL,QAAQ,EAAQ,CACd,OAAO,EAAW,IAAA,GAAY,EAAQ,QAAQ,CAAM,CACtD,EACA,SAAU,CACJ,IACJ,EAAW,GACX,EAAe,EACf,EAAM,QAAQ,EAChB,CACF,CACF,CAEA,SAAgB,EAAqB,EAA8C,CACjF,IAAM,EAAS,EAAQ,aAAa,KAAK,EACzC,MAAO,CACL,QAAS,CAAC,CAAE,KAAM,OAAQ,KAAM,EAAS,GAAG,EAAO,MAAM,IAAuB,CAAmB,CAAC,EACpG,UACA,UAAW,EACb,CACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { QuestionParams } from "../../schemas/questionnaire.cjs";
|
|
2
|
+
import { QuestionnaireResult, ToolTextResult } from "../../types/questionnaire.cjs";
|
|
3
|
+
import { MinorModeCatalogClient } from "@agimon-ai/doompi-extension-contracts/mode";
|
|
4
|
+
import { NarrationRequester } from "@agimon-ai/doompi-extension-contracts/narration";
|
|
5
|
+
import { ProtocolRuntimeOptions } from "@agimon-ai/doompi-extension-contracts/protocol";
|
|
6
|
+
//#region src/adapters/doom/voiceQuestionHandoff.d.ts
|
|
7
|
+
declare const DOOM_VOICE_SOURCE = "@agimon-ai/doompi-voice";
|
|
8
|
+
declare const DOOM_VOICE_AUTO_MODE_ID = "voice-auto";
|
|
9
|
+
declare const VOICE_WAIT_MESSAGE = "The questions were spoken through autonomous voice. Stop now and wait for the user's next message; it will arrive as an ordinary user message.";
|
|
10
|
+
declare function formatVoiceQuestionPrompt(params: QuestionParams): string;
|
|
11
|
+
declare class VoiceQuestionHandoff {
|
|
12
|
+
private readonly modes;
|
|
13
|
+
private readonly narration;
|
|
14
|
+
private readonly buildNarration;
|
|
15
|
+
constructor(modes: Pick<MinorModeCatalogClient, 'list'>, narration: NarrationRequester, buildNarration: (params: QuestionParams) => string);
|
|
16
|
+
handoff(params: QuestionParams): QuestionnaireResult | undefined;
|
|
17
|
+
}
|
|
18
|
+
interface VoiceQuestionHandoffHandle {
|
|
19
|
+
handoff(params: QuestionParams): QuestionnaireResult | undefined;
|
|
20
|
+
dispose(): void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Bind one session-scoped autonomous-voice handoff.
|
|
24
|
+
*
|
|
25
|
+
* The returned handle owns the external catalog subscription and must be
|
|
26
|
+
* disposed when its session is replaced or shut down.
|
|
27
|
+
*/
|
|
28
|
+
declare function createVoiceQuestionHandoff(options: ProtocolRuntimeOptions): VoiceQuestionHandoffHandle;
|
|
29
|
+
declare function buildVoiceToolResult(details: QuestionnaireResult): ToolTextResult;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { DOOM_VOICE_AUTO_MODE_ID, DOOM_VOICE_SOURCE, VOICE_WAIT_MESSAGE, VoiceQuestionHandoff, VoiceQuestionHandoffHandle, buildVoiceToolResult, createVoiceQuestionHandoff, formatVoiceQuestionPrompt };
|
|
32
|
+
//# sourceMappingURL=voiceQuestionHandoff.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voiceQuestionHandoff.d.cts","names":[],"sources":["../../../src/adapters/doom/voiceQuestionHandoff.ts"],"mappings":";;;;;;cAWa;cACA;cACA;iBAWG,0BAA0B,QAAQ;cAWrC;mBAEQ;mBACA;mBACA;EAFA,YAAA,OAAO,KAAK,iCACZ,WAAW,oBACX,iBAAiB,QAAQ;EAG5C,QAAQ,QAAQ,iBAAiB;;UAalB;EACf,QAAQ,QAAQ,iBAAiB;EACjC;;;;;;;;iBASc,2BAA2B,SAAS,yBAAyB;iBAmB7D,qBAAqB,SAAS,sBAAsB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { QuestionParams } from "../../schemas/questionnaire.mjs";
|
|
2
|
+
import { QuestionnaireResult, ToolTextResult } from "../../types/questionnaire.mjs";
|
|
3
|
+
import { MinorModeCatalogClient } from "@agimon-ai/doompi-extension-contracts/mode";
|
|
4
|
+
import { NarrationRequester } from "@agimon-ai/doompi-extension-contracts/narration";
|
|
5
|
+
import { ProtocolRuntimeOptions } from "@agimon-ai/doompi-extension-contracts/protocol";
|
|
6
|
+
//#region src/adapters/doom/voiceQuestionHandoff.d.ts
|
|
7
|
+
declare const DOOM_VOICE_SOURCE = "@agimon-ai/doompi-voice";
|
|
8
|
+
declare const DOOM_VOICE_AUTO_MODE_ID = "voice-auto";
|
|
9
|
+
declare const VOICE_WAIT_MESSAGE = "The questions were spoken through autonomous voice. Stop now and wait for the user's next message; it will arrive as an ordinary user message.";
|
|
10
|
+
declare function formatVoiceQuestionPrompt(params: QuestionParams): string;
|
|
11
|
+
declare class VoiceQuestionHandoff {
|
|
12
|
+
private readonly modes;
|
|
13
|
+
private readonly narration;
|
|
14
|
+
private readonly buildNarration;
|
|
15
|
+
constructor(modes: Pick<MinorModeCatalogClient, 'list'>, narration: NarrationRequester, buildNarration: (params: QuestionParams) => string);
|
|
16
|
+
handoff(params: QuestionParams): QuestionnaireResult | undefined;
|
|
17
|
+
}
|
|
18
|
+
interface VoiceQuestionHandoffHandle {
|
|
19
|
+
handoff(params: QuestionParams): QuestionnaireResult | undefined;
|
|
20
|
+
dispose(): void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Bind one session-scoped autonomous-voice handoff.
|
|
24
|
+
*
|
|
25
|
+
* The returned handle owns the external catalog subscription and must be
|
|
26
|
+
* disposed when its session is replaced or shut down.
|
|
27
|
+
*/
|
|
28
|
+
declare function createVoiceQuestionHandoff(options: ProtocolRuntimeOptions): VoiceQuestionHandoffHandle;
|
|
29
|
+
declare function buildVoiceToolResult(details: QuestionnaireResult): ToolTextResult;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { DOOM_VOICE_AUTO_MODE_ID, DOOM_VOICE_SOURCE, VOICE_WAIT_MESSAGE, VoiceQuestionHandoff, VoiceQuestionHandoffHandle, buildVoiceToolResult, createVoiceQuestionHandoff, formatVoiceQuestionPrompt };
|
|
32
|
+
//# sourceMappingURL=voiceQuestionHandoff.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voiceQuestionHandoff.d.mts","names":[],"sources":["../../../src/adapters/doom/voiceQuestionHandoff.ts"],"mappings":";;;;;;cAWa;cACA;cACA;iBAWG,0BAA0B,QAAQ;cAWrC;mBAEQ;mBACA;mBACA;EAFA,YAAA,OAAO,KAAK,iCACZ,WAAW,oBACX,iBAAiB,QAAQ;EAG5C,QAAQ,QAAQ,iBAAiB;;UAalB;EACf,QAAQ,QAAQ,iBAAiB;EACjC;;;;;;;;iBASc,2BAA2B,SAAS,yBAAyB;iBAmB7D,qBAAqB,SAAS,sBAAsB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const
|
|
1
|
+
import{buildVoiceQuestionNarration as e}from"../../services/voiceQuestionNarration.mjs";import{createMinorModeCatalogClient as t}from"@agimon-ai/doompi-extension-contracts/mode";import{createNarrationRequester as n}from"@agimon-ai/doompi-extension-contracts/narration";import{createProtocolRuntime as r}from"@agimon-ai/doompi-extension-contracts/protocol";const i=`@agimon-ai/doompi-voice`,a=`voice-auto`,o=`The questions were spoken through autonomous voice. Stop now and wait for the user's next message; it will arrive as an ordinary user message.`;function s(e){return e.descriptor.source===`@agimon-ai/doompi-voice`&&e.descriptor.id===`voice-auto`&&e.state.activation===`active`}function c(e){let t=e.questions.length>1;return e.questions.map((e,n)=>[`${t?`${n+1}. `:``}${e.question}${e.multiSelect?` (Select all that apply.)`:``}`,...e.options.map((e,t)=>` ${t+1}. ${e.label}`),` Type something.`].join(`
|
|
2
2
|
`)).join(`
|
|
3
3
|
|
|
4
|
-
`)}var
|
|
4
|
+
`)}var l=class{modes;narration;buildNarration;constructor(e,t,n){this.modes=e,this.narration=t,this.buildNarration=n}handoff(e){if(this.modes.list().some(s))return this.narration.narrate(this.buildNarration(e)),{answers:[],cancelled:!1,delivery:`voice`,awaitingResponse:!0,voicePrompt:c(e)}}};function u(i){let a=t(),o=a.bind(r(i)),s=new l(a,n(i),e),c=!1;return{handoff(e){return c?void 0:s.handoff(e)},dispose(){c||(c=!0,o(),a.dispose())}}}function d(e){let t=e.voicePrompt?.trim();return{content:[{type:`text`,text:t?`${t}\n\n${o}`:o}],details:e,terminate:!0}}export{a as DOOM_VOICE_AUTO_MODE_ID,i as DOOM_VOICE_SOURCE,o as VOICE_WAIT_MESSAGE,l as VoiceQuestionHandoff,d as buildVoiceToolResult,u as createVoiceQuestionHandoff,c as formatVoiceQuestionPrompt};
|
|
5
5
|
//# sourceMappingURL=voiceQuestionHandoff.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voiceQuestionHandoff.mjs","names":[],"sources":["../../../src/adapters/doom/voiceQuestionHandoff.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"voiceQuestionHandoff.mjs","names":[],"sources":["../../../src/adapters/doom/voiceQuestionHandoff.ts"],"sourcesContent":["import {\n createMinorModeCatalogClient,\n type MinorModeCatalogClient,\n type MinorModeRecord,\n} from '@agimon-ai/doompi-extension-contracts/mode';\nimport { createNarrationRequester, type NarrationRequester } from '@agimon-ai/doompi-extension-contracts/narration';\nimport { createProtocolRuntime, type ProtocolRuntimeOptions } from '@agimon-ai/doompi-extension-contracts/protocol';\nimport type { QuestionParams } from '../../schemas/questionnaire.js';\nimport { buildVoiceQuestionNarration } from '../../services/voiceQuestionNarration.js';\nimport type { QuestionnaireResult, ToolTextResult } from '../../types/questionnaire.js';\n\nexport const DOOM_VOICE_SOURCE = '@agimon-ai/doompi-voice';\nexport const DOOM_VOICE_AUTO_MODE_ID = 'voice-auto';\nexport const VOICE_WAIT_MESSAGE =\n \"The questions were spoken through autonomous voice. Stop now and wait for the user's next message; it will arrive as an ordinary user message.\";\n\nfunction isAutonomousVoice(record: MinorModeRecord): boolean {\n return (\n record.descriptor.source === DOOM_VOICE_SOURCE &&\n record.descriptor.id === DOOM_VOICE_AUTO_MODE_ID &&\n record.state.activation === 'active'\n );\n}\n\nexport function formatVoiceQuestionPrompt(params: QuestionParams): string {\n const numberQuestions = params.questions.length > 1;\n return params.questions\n .map((question, questionIndex) => {\n const heading = `${numberQuestions ? `${questionIndex + 1}. ` : ''}${question.question}${question.multiSelect ? ' (Select all that apply.)' : ''}`;\n const options = question.options.map((option, optionIndex) => ` ${optionIndex + 1}. ${option.label}`);\n return [heading, ...options, ' Type something.'].join('\\n');\n })\n .join('\\n\\n');\n}\n\nexport class VoiceQuestionHandoff {\n constructor(\n private readonly modes: Pick<MinorModeCatalogClient, 'list'>,\n private readonly narration: NarrationRequester,\n private readonly buildNarration: (params: QuestionParams) => string,\n ) {}\n\n handoff(params: QuestionParams): QuestionnaireResult | undefined {\n if (!this.modes.list().some(isAutonomousVoice)) return undefined;\n this.narration.narrate(this.buildNarration(params));\n return {\n answers: [],\n cancelled: false,\n delivery: 'voice',\n awaitingResponse: true,\n voicePrompt: formatVoiceQuestionPrompt(params),\n };\n }\n}\n\nexport interface VoiceQuestionHandoffHandle {\n handoff(params: QuestionParams): QuestionnaireResult | undefined;\n dispose(): void;\n}\n\n/**\n * Bind one session-scoped autonomous-voice handoff.\n *\n * The returned handle owns the external catalog subscription and must be\n * disposed when its session is replaced or shut down.\n */\nexport function createVoiceQuestionHandoff(options: ProtocolRuntimeOptions): VoiceQuestionHandoffHandle {\n const modes = createMinorModeCatalogClient();\n const disposeBinding = modes.bind(createProtocolRuntime(options));\n const handoff = new VoiceQuestionHandoff(modes, createNarrationRequester(options), buildVoiceQuestionNarration);\n let disposed = false;\n\n return {\n handoff(params) {\n return disposed ? undefined : handoff.handoff(params);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n disposeBinding();\n modes.dispose();\n },\n };\n}\n\nexport function buildVoiceToolResult(details: QuestionnaireResult): ToolTextResult {\n const prompt = details.voicePrompt?.trim();\n return {\n content: [{ type: 'text', text: prompt ? `${prompt}\\n\\n${VOICE_WAIT_MESSAGE}` : VOICE_WAIT_MESSAGE }],\n details,\n terminate: true,\n };\n}\n"],"mappings":"oWAWA,MAAa,EAAoB,0BACpB,EAA0B,aAC1B,EACX,iJAEF,SAAS,EAAkB,EAAkC,CAC3D,OACE,EAAO,WAAW,SAAA,2BAClB,EAAO,WAAW,KAAA,cAClB,EAAO,MAAM,aAAe,QAEhC,CAEA,SAAgB,EAA0B,EAAgC,CACxE,IAAM,EAAkB,EAAO,UAAU,OAAS,EAClD,OAAO,EAAO,UACX,KAAK,EAAU,IAGP,CAAC,GAFW,EAAkB,GAAG,EAAgB,EAAE,IAAM,KAAK,EAAS,WAAW,EAAS,YAAc,4BAA8B,KAE7H,GADD,EAAS,QAAQ,KAAK,EAAQ,IAAgB,KAAK,EAAc,EAAE,IAAI,EAAO,OACpE,EAAG,mBAAmB,CAAC,CAAC,KAAK;CAAI,CAC5D,CAAC,CACD,KAAK;;CAAM,CAChB,CAEA,IAAa,EAAb,KAAkC,CAEb,MACA,UACA,eAHnB,YACE,EACA,EACA,EACA,CAHiB,KAAA,MAAA,EACA,KAAA,UAAA,EACA,KAAA,eAAA,CAChB,CAEH,QAAQ,EAAyD,CAC1D,QAAK,MAAM,KAAK,CAAC,CAAC,KAAK,CAAiB,EAE7C,OADA,KAAK,UAAU,QAAQ,KAAK,eAAe,CAAM,CAAC,EAC3C,CACL,QAAS,CAAC,EACV,UAAW,GACX,SAAU,QACV,iBAAkB,GAClB,YAAa,EAA0B,CAAM,CAC/C,CACF,CACF,EAaA,SAAgB,EAA2B,EAA6D,CACtG,IAAM,EAAQ,EAA6B,EACrC,EAAiB,EAAM,KAAK,EAAsB,CAAO,CAAC,EAC1D,EAAU,IAAI,EAAqB,EAAO,EAAyB,CAAO,EAAG,CAA2B,EAC1G,EAAW,GAEf,MAAO,CACL,QAAQ,EAAQ,CACd,OAAO,EAAW,IAAA,GAAY,EAAQ,QAAQ,CAAM,CACtD,EACA,SAAU,CACJ,IACJ,EAAW,GACX,EAAe,EACf,EAAM,QAAQ,EAChB,CACF,CACF,CAEA,SAAgB,EAAqB,EAA8C,CACjF,IAAM,EAAS,EAAQ,aAAa,KAAK,EACzC,MAAO,CACL,QAAS,CAAC,CAAE,KAAM,OAAQ,KAAM,EAAS,GAAG,EAAO,MAAM,IAAuB,CAAmB,CAAC,EACpG,UACA,UAAW,EACb,CACF"}
|
package/dist/extensions/pi.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../adapters/doom/voiceQuestionHandoff.cjs"),t=require("../adapters/pi/askUserQuestionAdapter.cjs"),n=require("../adapters/pi/reconcileAdapter.cjs"),r=require("../services/questionnaireCoordinator.cjs"),i
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../adapters/doom/voiceQuestionHandoff.cjs"),t=require("../adapters/pi/askUserQuestionAdapter.cjs"),n=require("../adapters/pi/reconcileAdapter.cjs"),r=require("../services/questionnaireCoordinator.cjs"),i=`@agimon-ai/doompi-user-feedback`,a=Symbol.for(`${i}/installed-hosts`);function o(e){let t=globalThis,n=t[a]??new WeakSet;return t[a]=n,!n.has(e)&&(n.add(e),!0)}function s(a){if(!o(a))return;let s=new r.QuestionnaireCoordinator,c,l=()=>{c?.dispose(),c=void 0};t.registerAskUserQuestionTool(a,{enqueue:(e,t)=>s.enqueue(e,t),runTui:async(...e)=>{let{runTuiQuestionnaire:t}=await Promise.resolve().then(()=>require("../tui/runQuestionnaire.cjs"));return t(...e)},tryVoice:e=>c?.handoff(e)}),n.registerAskUserQuestionReconciler(a),a.on(`session_start`,(t,n)=>{s.shutdown(),s=new r.QuestionnaireCoordinator,l(),c=e.createVoiceQuestionHandoff({bus:a.events,source:i,sessionId:n.sessionManager.getSessionId()})}),a.on(`session_shutdown`,()=>{s.shutdown(),l()})}exports.default=s,exports.registerUserFeedbackExtension=s;
|
|
2
2
|
//# sourceMappingURL=pi.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.cjs","names":["QuestionnaireCoordinator","
|
|
1
|
+
{"version":3,"file":"pi.cjs","names":["QuestionnaireCoordinator","createVoiceQuestionHandoff"],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport { createVoiceQuestionHandoff, type VoiceQuestionHandoffHandle } from '../adapters/doom/voiceQuestionHandoff.js';\nimport { registerAskUserQuestionTool } from '../adapters/pi/askUserQuestionAdapter.js';\nimport { registerAskUserQuestionReconciler } from '../adapters/pi/reconcileAdapter.js';\nimport { QuestionnaireCoordinator } from '../services/questionnaireCoordinator.js';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-user-feedback';\nconst INSTALLATIONS_KEY = Symbol.for(`${PACKAGE_SOURCE}/installed-hosts`);\n\ntype InstallationRegistry = typeof globalThis & {\n [INSTALLATIONS_KEY]?: WeakSet<object>;\n};\n\nfunction claimHostInstallation(pi: ExtensionAPI): boolean {\n const registry = globalThis as InstallationRegistry;\n const installedHosts = registry[INSTALLATIONS_KEY] ?? new WeakSet<object>();\n registry[INSTALLATIONS_KEY] = installedHosts;\n if (installedHosts.has(pi)) return false;\n installedHosts.add(pi);\n return true;\n}\n\nexport function registerUserFeedbackExtension(pi: ExtensionAPI): void {\n if (!claimHostInstallation(pi)) return;\n\n let coordinator = new QuestionnaireCoordinator();\n let voiceHandoff: VoiceQuestionHandoffHandle | undefined;\n const resetVoiceHandoff = (): void => {\n voiceHandoff?.dispose();\n voiceHandoff = undefined;\n };\n\n registerAskUserQuestionTool(pi, {\n enqueue: (runner, signal) => coordinator.enqueue(runner, signal),\n runTui: async (...args) => {\n const { runTuiQuestionnaire } = await import('../tui/runQuestionnaire.js');\n return runTuiQuestionnaire(...args);\n },\n tryVoice: (params) => voiceHandoff?.handoff(params),\n });\n registerAskUserQuestionReconciler(pi);\n\n pi.on('session_start', (_event, context) => {\n coordinator.shutdown();\n coordinator = new QuestionnaireCoordinator();\n resetVoiceHandoff();\n\n voiceHandoff = createVoiceQuestionHandoff({\n bus: pi.events,\n source: PACKAGE_SOURCE,\n sessionId: context.sessionManager.getSessionId(),\n });\n });\n pi.on('session_shutdown', () => {\n coordinator.shutdown();\n resetVoiceHandoff();\n });\n}\n\nexport { registerUserFeedbackExtension as default };\n"],"mappings":"0TAMM,EAAiB,kCACjB,EAAoB,OAAO,IAAI,GAAG,EAAe,iBAAiB,EAMxE,SAAS,EAAsB,EAA2B,CACxD,IAAM,EAAW,WACX,EAAiB,EAAS,IAAsB,IAAI,QAI1D,MAHA,GAAS,GAAqB,EAC9B,CAAI,EAAe,IAAI,CAAE,IACzB,EAAe,IAAI,CAAE,EACd,GACT,CAEA,SAAgB,EAA8B,EAAwB,CACpE,GAAI,CAAC,EAAsB,CAAE,EAAG,OAEhC,IAAI,EAAc,IAAIA,EAAAA,yBAClB,EACE,MAAgC,CACpC,GAAc,QAAQ,EACtB,EAAe,IAAA,EACjB,EAEA,EAAA,4BAA4B,EAAI,CAC9B,SAAU,EAAQ,IAAW,EAAY,QAAQ,EAAQ,CAAM,EAC/D,OAAQ,MAAO,GAAG,IAAS,CACzB,GAAM,CAAE,uBAAwB,MAAA,QAAA,QAAA,CAAA,CAAA,SAAA,QAAM,6BAAA,CAAA,EACtC,OAAO,EAAoB,GAAG,CAAI,CACpC,EACA,SAAW,GAAW,GAAc,QAAQ,CAAM,CACpD,CAAC,EACD,EAAA,kCAAkC,CAAE,EAEpC,EAAG,GAAG,iBAAkB,EAAQ,IAAY,CAC1C,EAAY,SAAS,EACrB,EAAc,IAAIA,EAAAA,yBAClB,EAAkB,EAElB,EAAeC,EAAAA,2BAA2B,CACxC,IAAK,EAAG,OACR,OAAQ,EACR,UAAW,EAAQ,eAAe,aAAa,CACjD,CAAC,CACH,CAAC,EACD,EAAG,GAAG,uBAA0B,CAC9B,EAAY,SAAS,EACrB,EAAkB,CACpB,CAAC,CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.d.cts","names":[],"sources":["../../src/extensions/pi.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"pi.d.cts","names":[],"sources":["../../src/extensions/pi.ts"],"mappings":";;iBAsBgB,8BAA8B,IAAI"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.d.mts","names":[],"sources":["../../src/extensions/pi.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"pi.d.mts","names":[],"sources":["../../src/extensions/pi.ts"],"mappings":";;iBAsBgB,8BAA8B,IAAI"}
|
package/dist/extensions/pi.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{createVoiceQuestionHandoff as e}from"../adapters/doom/voiceQuestionHandoff.mjs";import{registerAskUserQuestionTool as t}from"../adapters/pi/askUserQuestionAdapter.mjs";import{registerAskUserQuestionReconciler as n}from"../adapters/pi/reconcileAdapter.mjs";import{QuestionnaireCoordinator as r}from"../services/questionnaireCoordinator.mjs";const i=`@agimon-ai/doompi-user-feedback`,a=Symbol.for(`${i}/installed-hosts`);function o(e){let t=globalThis,n=t[a]??new WeakSet;return t[a]=n,!n.has(e)&&(n.add(e),!0)}function s(a){if(!o(a))return;let s=new r,c,l=()=>{c?.dispose(),c=void 0};t(a,{enqueue:(e,t)=>s.enqueue(e,t),runTui:async(...e)=>{let{runTuiQuestionnaire:t}=await import(`../tui/runQuestionnaire.mjs`);return t(...e)},tryVoice:e=>c?.handoff(e)}),n(a),a.on(`session_start`,(t,n)=>{s.shutdown(),s=new r,l(),c=e({bus:a.events,source:i,sessionId:n.sessionManager.getSessionId()})}),a.on(`session_shutdown`,()=>{s.shutdown(),l()})}export{s as default,s as registerUserFeedbackExtension};
|
|
2
2
|
//# sourceMappingURL=pi.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.mjs","names":[],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"pi.mjs","names":[],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\nimport { createVoiceQuestionHandoff, type VoiceQuestionHandoffHandle } from '../adapters/doom/voiceQuestionHandoff.js';\nimport { registerAskUserQuestionTool } from '../adapters/pi/askUserQuestionAdapter.js';\nimport { registerAskUserQuestionReconciler } from '../adapters/pi/reconcileAdapter.js';\nimport { QuestionnaireCoordinator } from '../services/questionnaireCoordinator.js';\n\nconst PACKAGE_SOURCE = '@agimon-ai/doompi-user-feedback';\nconst INSTALLATIONS_KEY = Symbol.for(`${PACKAGE_SOURCE}/installed-hosts`);\n\ntype InstallationRegistry = typeof globalThis & {\n [INSTALLATIONS_KEY]?: WeakSet<object>;\n};\n\nfunction claimHostInstallation(pi: ExtensionAPI): boolean {\n const registry = globalThis as InstallationRegistry;\n const installedHosts = registry[INSTALLATIONS_KEY] ?? new WeakSet<object>();\n registry[INSTALLATIONS_KEY] = installedHosts;\n if (installedHosts.has(pi)) return false;\n installedHosts.add(pi);\n return true;\n}\n\nexport function registerUserFeedbackExtension(pi: ExtensionAPI): void {\n if (!claimHostInstallation(pi)) return;\n\n let coordinator = new QuestionnaireCoordinator();\n let voiceHandoff: VoiceQuestionHandoffHandle | undefined;\n const resetVoiceHandoff = (): void => {\n voiceHandoff?.dispose();\n voiceHandoff = undefined;\n };\n\n registerAskUserQuestionTool(pi, {\n enqueue: (runner, signal) => coordinator.enqueue(runner, signal),\n runTui: async (...args) => {\n const { runTuiQuestionnaire } = await import('../tui/runQuestionnaire.js');\n return runTuiQuestionnaire(...args);\n },\n tryVoice: (params) => voiceHandoff?.handoff(params),\n });\n registerAskUserQuestionReconciler(pi);\n\n pi.on('session_start', (_event, context) => {\n coordinator.shutdown();\n coordinator = new QuestionnaireCoordinator();\n resetVoiceHandoff();\n\n voiceHandoff = createVoiceQuestionHandoff({\n bus: pi.events,\n source: PACKAGE_SOURCE,\n sessionId: context.sessionManager.getSessionId(),\n });\n });\n pi.on('session_shutdown', () => {\n coordinator.shutdown();\n resetVoiceHandoff();\n });\n}\n\nexport { registerUserFeedbackExtension as default };\n"],"mappings":"2VAMA,MAAM,EAAiB,kCACjB,EAAoB,OAAO,IAAI,GAAG,EAAe,iBAAiB,EAMxE,SAAS,EAAsB,EAA2B,CACxD,IAAM,EAAW,WACX,EAAiB,EAAS,IAAsB,IAAI,QAI1D,MAHA,GAAS,GAAqB,EAC9B,CAAI,EAAe,IAAI,CAAE,IACzB,EAAe,IAAI,CAAE,EACd,GACT,CAEA,SAAgB,EAA8B,EAAwB,CACpE,GAAI,CAAC,EAAsB,CAAE,EAAG,OAEhC,IAAI,EAAc,IAAI,EAClB,EACE,MAAgC,CACpC,GAAc,QAAQ,EACtB,EAAe,IAAA,EACjB,EAEA,EAA4B,EAAI,CAC9B,SAAU,EAAQ,IAAW,EAAY,QAAQ,EAAQ,CAAM,EAC/D,OAAQ,MAAO,GAAG,IAAS,CACzB,GAAM,CAAE,uBAAwB,MAAM,OAAO,+BAC7C,OAAO,EAAoB,GAAG,CAAI,CACpC,EACA,SAAW,GAAW,GAAc,QAAQ,CAAM,CACpD,CAAC,EACD,EAAkC,CAAE,EAEpC,EAAG,GAAG,iBAAkB,EAAQ,IAAY,CAC1C,EAAY,SAAS,EACrB,EAAc,IAAI,EAClB,EAAkB,EAElB,EAAe,EAA2B,CACxC,IAAK,EAAG,OACR,OAAQ,EACR,UAAW,EAAQ,eAAe,aAAa,CACjD,CAAC,CACH,CAAC,EACD,EAAG,GAAG,uBAA0B,CAC9B,EAAY,SAAS,EACrB,EAAkB,CACpB,CAAC,CACH"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Static, Type } from "typebox";
|
|
2
|
+
//#region src/schemas/questionnaire.d.ts
|
|
3
|
+
declare const QuestionParamsSchema: Type.TObject<{
|
|
4
|
+
questions: Type.TArray<Type.TObject<{
|
|
5
|
+
question: Type.TString;
|
|
6
|
+
header: Type.TString;
|
|
7
|
+
options: Type.TArray<Type.TObject<{
|
|
8
|
+
label: Type.TString;
|
|
9
|
+
description: Type.TString;
|
|
10
|
+
preview: Type.TOptional<Type.TString>;
|
|
11
|
+
}>>;
|
|
12
|
+
multiSelect: Type.TOptional<Type.TBoolean>;
|
|
13
|
+
}>>;
|
|
14
|
+
}>;
|
|
15
|
+
type QuestionParams = Static<typeof QuestionParamsSchema>;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { QuestionParams, QuestionParamsSchema };
|
|
18
|
+
//# sourceMappingURL=questionnaire.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"questionnaire.d.cts","names":[],"sources":["../../src/schemas/questionnaire.ts"],"mappings":";;cA6Ca,sBAAoB,KAAA;;;;;;;;;;;;KAarB,iBAAiB,cAAc"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Static, Type } from "typebox";
|
|
2
|
+
//#region src/schemas/questionnaire.d.ts
|
|
3
|
+
declare const QuestionParamsSchema: Type.TObject<{
|
|
4
|
+
questions: Type.TArray<Type.TObject<{
|
|
5
|
+
question: Type.TString;
|
|
6
|
+
header: Type.TString;
|
|
7
|
+
options: Type.TArray<Type.TObject<{
|
|
8
|
+
label: Type.TString;
|
|
9
|
+
description: Type.TString;
|
|
10
|
+
preview: Type.TOptional<Type.TString>;
|
|
11
|
+
}>>;
|
|
12
|
+
multiSelect: Type.TOptional<Type.TBoolean>;
|
|
13
|
+
}>>;
|
|
14
|
+
}>;
|
|
15
|
+
type QuestionParams = Static<typeof QuestionParamsSchema>;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { QuestionParams, QuestionParamsSchema };
|
|
18
|
+
//# sourceMappingURL=questionnaire.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"questionnaire.d.mts","names":[],"sources":["../../src/schemas/questionnaire.ts"],"mappings":";;cA6Ca,sBAAoB,KAAA;;;;;;;;;;;;KAarB,iBAAiB,cAAc"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/types/questionnaire.d.ts
|
|
2
|
+
type AnswerKind = 'option' | 'custom' | 'multi';
|
|
3
|
+
interface QuestionAnswer {
|
|
4
|
+
questionIndex: number;
|
|
5
|
+
question: string;
|
|
6
|
+
kind: AnswerKind;
|
|
7
|
+
answer: string | null;
|
|
8
|
+
selected?: string[];
|
|
9
|
+
notes?: string;
|
|
10
|
+
preview?: string;
|
|
11
|
+
}
|
|
12
|
+
type QuestionnaireError = 'no_ui' | 'no_custom_ui' | 'no_questions' | 'empty_options' | 'too_many_questions' | 'duplicate_question' | 'duplicate_option_label' | 'reserved_label' | 'session_load_failed' | 'stale_module_cache';
|
|
13
|
+
interface QuestionnaireResult {
|
|
14
|
+
answers: QuestionAnswer[];
|
|
15
|
+
cancelled: boolean;
|
|
16
|
+
error?: QuestionnaireError;
|
|
17
|
+
delivery?: 'voice';
|
|
18
|
+
awaitingResponse?: boolean;
|
|
19
|
+
voicePrompt?: string;
|
|
20
|
+
}
|
|
21
|
+
interface ToolTextResult {
|
|
22
|
+
content: Array<{
|
|
23
|
+
type: 'text';
|
|
24
|
+
text: string;
|
|
25
|
+
}>;
|
|
26
|
+
details: QuestionnaireResult;
|
|
27
|
+
terminate?: boolean;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { AnswerKind, QuestionAnswer, QuestionnaireError, QuestionnaireResult, ToolTextResult };
|
|
31
|
+
//# sourceMappingURL=questionnaire.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"questionnaire.d.cts","names":[],"sources":["../../src/types/questionnaire.ts"],"mappings":";KAAY;UAEK;EACf;EACA;EACA,MAAM;EACN;EACA;EACA;EACA;;KAGU;UAgBK;EACf,SAAS;EACT;EACA,QAAQ;EACR;EACA;EACA;;UAGe;EACf,SAAS;IAAQ;IAAc;;EAC/B,SAAS;EACT"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/types/questionnaire.d.ts
|
|
2
|
+
type AnswerKind = 'option' | 'custom' | 'multi';
|
|
3
|
+
interface QuestionAnswer {
|
|
4
|
+
questionIndex: number;
|
|
5
|
+
question: string;
|
|
6
|
+
kind: AnswerKind;
|
|
7
|
+
answer: string | null;
|
|
8
|
+
selected?: string[];
|
|
9
|
+
notes?: string;
|
|
10
|
+
preview?: string;
|
|
11
|
+
}
|
|
12
|
+
type QuestionnaireError = 'no_ui' | 'no_custom_ui' | 'no_questions' | 'empty_options' | 'too_many_questions' | 'duplicate_question' | 'duplicate_option_label' | 'reserved_label' | 'session_load_failed' | 'stale_module_cache';
|
|
13
|
+
interface QuestionnaireResult {
|
|
14
|
+
answers: QuestionAnswer[];
|
|
15
|
+
cancelled: boolean;
|
|
16
|
+
error?: QuestionnaireError;
|
|
17
|
+
delivery?: 'voice';
|
|
18
|
+
awaitingResponse?: boolean;
|
|
19
|
+
voicePrompt?: string;
|
|
20
|
+
}
|
|
21
|
+
interface ToolTextResult {
|
|
22
|
+
content: Array<{
|
|
23
|
+
type: 'text';
|
|
24
|
+
text: string;
|
|
25
|
+
}>;
|
|
26
|
+
details: QuestionnaireResult;
|
|
27
|
+
terminate?: boolean;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { AnswerKind, QuestionAnswer, QuestionnaireError, QuestionnaireResult, ToolTextResult };
|
|
31
|
+
//# sourceMappingURL=questionnaire.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"questionnaire.d.mts","names":[],"sources":["../../src/types/questionnaire.ts"],"mappings":";KAAY;UAEK;EACf;EACA;EACA,MAAM;EACN;EACA;EACA;EACA;;KAGU;UAgBK;EACf,SAAS;EACT;EACA,QAAQ;EACR;EACA;EACA;;UAGe;EACf,SAAS;IAAQ;IAAc;;EAC/B,SAAS;EACT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./adapters/doom/voiceQuestionHandoff.cjs");exports.DOOM_VOICE_AUTO_MODE_ID=e.DOOM_VOICE_AUTO_MODE_ID,exports.DOOM_VOICE_SOURCE=e.DOOM_VOICE_SOURCE,exports.VOICE_WAIT_MESSAGE=e.VOICE_WAIT_MESSAGE,exports.VoiceQuestionHandoff=e.VoiceQuestionHandoff,exports.buildVoiceToolResult=e.buildVoiceToolResult,exports.createVoiceQuestionHandoff=e.createVoiceQuestionHandoff,exports.formatVoiceQuestionPrompt=e.formatVoiceQuestionPrompt;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { QuestionParams } from "./schemas/questionnaire.cjs";
|
|
2
|
+
import { QuestionnaireResult, ToolTextResult } from "./types/questionnaire.cjs";
|
|
3
|
+
import { DOOM_VOICE_AUTO_MODE_ID, DOOM_VOICE_SOURCE, VOICE_WAIT_MESSAGE, VoiceQuestionHandoff, VoiceQuestionHandoffHandle, buildVoiceToolResult, createVoiceQuestionHandoff, formatVoiceQuestionPrompt } from "./adapters/doom/voiceQuestionHandoff.cjs";
|
|
4
|
+
export { DOOM_VOICE_AUTO_MODE_ID, DOOM_VOICE_SOURCE, type QuestionParams, type QuestionnaireResult, type ToolTextResult, VOICE_WAIT_MESSAGE, VoiceQuestionHandoff, type VoiceQuestionHandoffHandle, buildVoiceToolResult, createVoiceQuestionHandoff, formatVoiceQuestionPrompt };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { QuestionParams } from "./schemas/questionnaire.mjs";
|
|
2
|
+
import { QuestionnaireResult, ToolTextResult } from "./types/questionnaire.mjs";
|
|
3
|
+
import { DOOM_VOICE_AUTO_MODE_ID, DOOM_VOICE_SOURCE, VOICE_WAIT_MESSAGE, VoiceQuestionHandoff, VoiceQuestionHandoffHandle, buildVoiceToolResult, createVoiceQuestionHandoff, formatVoiceQuestionPrompt } from "./adapters/doom/voiceQuestionHandoff.mjs";
|
|
4
|
+
export { DOOM_VOICE_AUTO_MODE_ID, DOOM_VOICE_SOURCE, type QuestionParams, type QuestionnaireResult, type ToolTextResult, VOICE_WAIT_MESSAGE, VoiceQuestionHandoff, type VoiceQuestionHandoffHandle, buildVoiceToolResult, createVoiceQuestionHandoff, formatVoiceQuestionPrompt };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{DOOM_VOICE_AUTO_MODE_ID as e,DOOM_VOICE_SOURCE as t,VOICE_WAIT_MESSAGE as n,VoiceQuestionHandoff as r,buildVoiceToolResult as i,createVoiceQuestionHandoff as a,formatVoiceQuestionPrompt as o}from"./adapters/doom/voiceQuestionHandoff.mjs";export{e as DOOM_VOICE_AUTO_MODE_ID,t as DOOM_VOICE_SOURCE,n as VOICE_WAIT_MESSAGE,r as VoiceQuestionHandoff,i as buildVoiceToolResult,a as createVoiceQuestionHandoff,o as formatVoiceQuestionPrompt};
|
package/package.json
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-user-feedback",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.11",
|
|
4
4
|
"description": "Structured user feedback for DoomPi agents",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai",
|
|
7
|
+
"coding-agent",
|
|
8
|
+
"developer-tools",
|
|
9
|
+
"doompi",
|
|
10
|
+
"pi-package"
|
|
11
|
+
],
|
|
5
12
|
"homepage": "https://agimon.ai",
|
|
6
13
|
"license": "MIT",
|
|
7
14
|
"author": "Vuong Ngo",
|
|
@@ -26,6 +33,11 @@
|
|
|
26
33
|
"import": "./dist/events.mjs",
|
|
27
34
|
"require": "./dist/events.cjs"
|
|
28
35
|
},
|
|
36
|
+
"./voice-question-handoff": {
|
|
37
|
+
"types": "./dist/voiceQuestionHandoff.d.mts",
|
|
38
|
+
"import": "./dist/voiceQuestionHandoff.mjs",
|
|
39
|
+
"require": "./dist/voiceQuestionHandoff.cjs"
|
|
40
|
+
},
|
|
29
41
|
"./extensions/pi": {
|
|
30
42
|
"types": "./dist/extensions/pi.d.mts",
|
|
31
43
|
"import": "./dist/extensions/pi.mjs",
|
|
@@ -38,12 +50,12 @@
|
|
|
38
50
|
},
|
|
39
51
|
"dependencies": {
|
|
40
52
|
"typebox": "1.1.38",
|
|
41
|
-
"@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.
|
|
42
|
-
"@agimon-ai/doompi-ui": "0.0.1-alpha.
|
|
53
|
+
"@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.22",
|
|
54
|
+
"@agimon-ai/doompi-ui": "0.0.1-alpha.22"
|
|
43
55
|
},
|
|
44
56
|
"devDependencies": {
|
|
45
|
-
"@earendil-works/pi-coding-agent": "0.84.
|
|
46
|
-
"@earendil-works/pi-tui": "0.84.
|
|
57
|
+
"@earendil-works/pi-coding-agent": "0.84.2",
|
|
58
|
+
"@earendil-works/pi-tui": "0.84.2",
|
|
47
59
|
"@types/node": "26.1.1",
|
|
48
60
|
"@vitest/coverage-v8": "4.1.10",
|
|
49
61
|
"tsdown": "0.22.14",
|
|
@@ -51,8 +63,8 @@
|
|
|
51
63
|
"vitest": "4.1.10"
|
|
52
64
|
},
|
|
53
65
|
"peerDependencies": {
|
|
54
|
-
"@earendil-works/pi-coding-agent": "0.84.
|
|
55
|
-
"@earendil-works/pi-tui": "0.84.
|
|
66
|
+
"@earendil-works/pi-coding-agent": "0.84.2",
|
|
67
|
+
"@earendil-works/pi-tui": "0.84.2"
|
|
56
68
|
},
|
|
57
69
|
"peerDependenciesMeta": {
|
|
58
70
|
"@earendil-works/pi-coding-agent": {
|