pi-ask-tool-extension 0.1.4 → 0.2.2
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 +54 -4
- package/package.json +5 -2
- package/src/ask-inline-note.ts +26 -5
- package/src/ask-inline-ui.ts +16 -9
- package/src/ask-tabs-ui.ts +16 -14
- package/src/index.ts +113 -24
package/README.md
CHANGED
|
@@ -68,7 +68,17 @@ ask({
|
|
|
68
68
|
Result example:
|
|
69
69
|
|
|
70
70
|
```txt
|
|
71
|
-
User
|
|
71
|
+
User answers:
|
|
72
|
+
auth: Session
|
|
73
|
+
|
|
74
|
+
Answer context:
|
|
75
|
+
Question 1 (auth)
|
|
76
|
+
Prompt: Which auth approach?
|
|
77
|
+
Options:
|
|
78
|
+
1. JWT
|
|
79
|
+
2. Session
|
|
80
|
+
Response:
|
|
81
|
+
Selected: Session
|
|
72
82
|
```
|
|
73
83
|
|
|
74
84
|
### Single question (multi-select)
|
|
@@ -89,7 +99,18 @@ ask({
|
|
|
89
99
|
Result example:
|
|
90
100
|
|
|
91
101
|
```txt
|
|
92
|
-
User
|
|
102
|
+
User answers:
|
|
103
|
+
features: [Logging, Metrics]
|
|
104
|
+
|
|
105
|
+
Answer context:
|
|
106
|
+
Question 1 (features)
|
|
107
|
+
Prompt: Which features should be enabled?
|
|
108
|
+
Options:
|
|
109
|
+
1. Logging
|
|
110
|
+
2. Metrics
|
|
111
|
+
3. Tracing
|
|
112
|
+
Response:
|
|
113
|
+
Selected: [Logging, Metrics]
|
|
93
114
|
```
|
|
94
115
|
|
|
95
116
|
### Multi-question (tab flow)
|
|
@@ -117,6 +138,23 @@ Result example:
|
|
|
117
138
|
User answers:
|
|
118
139
|
auth: Session
|
|
119
140
|
cache: Redis
|
|
141
|
+
|
|
142
|
+
Answer context:
|
|
143
|
+
Question 1 (auth)
|
|
144
|
+
Prompt: Which auth approach?
|
|
145
|
+
Options:
|
|
146
|
+
1. JWT
|
|
147
|
+
2. Session
|
|
148
|
+
Response:
|
|
149
|
+
Selected: Session
|
|
150
|
+
|
|
151
|
+
Question 2 (cache)
|
|
152
|
+
Prompt: Which cache strategy?
|
|
153
|
+
Options:
|
|
154
|
+
1. Redis
|
|
155
|
+
2. None
|
|
156
|
+
Response:
|
|
157
|
+
Selected: Redis
|
|
120
158
|
```
|
|
121
159
|
|
|
122
160
|
## Interaction Model
|
|
@@ -168,10 +206,22 @@ For `Other`, a note is required to become valid.
|
|
|
168
206
|
|
|
169
207
|
```bash
|
|
170
208
|
npm install
|
|
171
|
-
npm
|
|
172
|
-
npm run typecheck
|
|
209
|
+
npm run check
|
|
173
210
|
```
|
|
174
211
|
|
|
212
|
+
`npm run check` runs:
|
|
213
|
+
|
|
214
|
+
- TypeScript checks (`npm run typecheck`)
|
|
215
|
+
- Test suite with coverage (`npm run test:coverage`)
|
|
216
|
+
- Coverage gate (`npm run coverage:check`)
|
|
217
|
+
|
|
218
|
+
Coverage gate defaults (override via env vars in CI if needed):
|
|
219
|
+
|
|
220
|
+
- Overall: lines >= 38%, functions >= 80%
|
|
221
|
+
- `src/index.ts`: lines >= 95%, functions >= 100%
|
|
222
|
+
- `src/ask-logic.ts`: lines >= 95%, functions >= 100%
|
|
223
|
+
- `src/ask-inline-note.ts`: lines >= 80%, functions >= 70%
|
|
224
|
+
|
|
175
225
|
## Project Structure
|
|
176
226
|
|
|
177
227
|
- `src/index.ts` - extension entrypoint, tool registration, and orchestration
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-ask-tool-extension",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Ask tool extension for pi with tabbed questioning and inline note editing",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -25,7 +25,10 @@
|
|
|
25
25
|
],
|
|
26
26
|
"scripts": {
|
|
27
27
|
"test": "bun test",
|
|
28
|
-
"
|
|
28
|
+
"test:coverage": "bun test --coverage --coverage-reporter=lcov --coverage-reporter=text",
|
|
29
|
+
"coverage:check": "node ./scripts/check-coverage.mjs",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"check": "npm run typecheck && npm run test:coverage && npm run coverage:check"
|
|
29
32
|
},
|
|
30
33
|
"peerDependencies": {
|
|
31
34
|
"@mariozechner/pi-coding-agent": "*",
|
package/src/ask-inline-note.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { wrapTextWithAnsi } from "@mariozechner/pi-tui";
|
|
2
|
+
|
|
1
3
|
const INLINE_NOTE_SEPARATOR = " — note: ";
|
|
2
4
|
const INLINE_EDIT_CURSOR = "▍";
|
|
3
5
|
|
|
6
|
+
export const INLINE_NOTE_WRAP_PADDING = 2;
|
|
7
|
+
|
|
4
8
|
function sanitizeNoteForInlineDisplay(rawNote: string): string {
|
|
5
9
|
return rawNote.replace(/[\r\n\t]/g, " ").replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "");
|
|
6
10
|
}
|
|
@@ -31,14 +35,31 @@ export function buildOptionLabelWithInlineNote(
|
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
const labelPrefix = `${baseOptionLabel}${INLINE_NOTE_SEPARATOR}`;
|
|
34
|
-
const
|
|
35
|
-
const
|
|
38
|
+
const inlineNote = isEditingNote ? `${sanitizedNote}${INLINE_EDIT_CURSOR}` : sanitizedNote.trim();
|
|
39
|
+
const inlineLabel = `${labelPrefix}${inlineNote}`;
|
|
36
40
|
|
|
37
41
|
if (maxInlineLabelLength == null) {
|
|
38
|
-
return
|
|
42
|
+
return inlineLabel;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
return isEditingNote
|
|
42
|
-
? truncateTextKeepingTail(
|
|
43
|
-
: truncateTextKeepingHead(
|
|
46
|
+
? truncateTextKeepingTail(inlineLabel, maxInlineLabelLength)
|
|
47
|
+
: truncateTextKeepingHead(inlineLabel, maxInlineLabelLength);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function buildWrappedOptionLabelWithInlineNote(
|
|
51
|
+
baseOptionLabel: string,
|
|
52
|
+
rawNote: string,
|
|
53
|
+
isEditingNote: boolean,
|
|
54
|
+
maxInlineLabelLength: number,
|
|
55
|
+
wrapPadding = INLINE_NOTE_WRAP_PADDING,
|
|
56
|
+
): string[] {
|
|
57
|
+
const inlineLabel = buildOptionLabelWithInlineNote(baseOptionLabel, rawNote, isEditingNote);
|
|
58
|
+
const sanitizedWrapPadding = Number.isFinite(wrapPadding) ? Math.max(0, Math.floor(wrapPadding)) : 0;
|
|
59
|
+
const sanitizedMaxInlineLabelLength = Number.isFinite(maxInlineLabelLength)
|
|
60
|
+
? Math.max(1, Math.floor(maxInlineLabelLength))
|
|
61
|
+
: 1;
|
|
62
|
+
const wrapWidth = Math.max(1, sanitizedMaxInlineLabelLength - sanitizedWrapPadding);
|
|
63
|
+
const wrappedLines = wrapTextWithAnsi(inlineLabel, wrapWidth);
|
|
64
|
+
return wrappedLines.length > 0 ? wrappedLines : [""];
|
|
44
65
|
}
|
package/src/ask-inline-ui.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExtensionUIContext } from "@mariozechner/pi-coding-agent";
|
|
2
|
-
import { Editor, type EditorTheme, Key, matchesKey, truncateToWidth } from "@mariozechner/pi-tui";
|
|
2
|
+
import { Editor, type EditorTheme, Key, matchesKey, truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
|
|
3
3
|
import {
|
|
4
4
|
OTHER_OPTION,
|
|
5
5
|
appendRecommendedTagToOptionLabels,
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
type AskOption,
|
|
8
8
|
type AskSelection,
|
|
9
9
|
} from "./ask-logic";
|
|
10
|
-
import {
|
|
10
|
+
import { INLINE_NOTE_WRAP_PADDING, buildWrappedOptionLabelWithInlineNote } from "./ask-inline-note";
|
|
11
11
|
|
|
12
12
|
interface SingleQuestionInput {
|
|
13
13
|
question: string;
|
|
@@ -115,21 +115,28 @@ export async function askSingleQuestionWithInlineNote(
|
|
|
115
115
|
addLine(theme.fg("text", ` ${questionInput.question}`));
|
|
116
116
|
renderedLines.push("");
|
|
117
117
|
|
|
118
|
-
const maxInlineLabelLength = Math.max(12, width - 6);
|
|
119
118
|
for (let optionIndex = 0; optionIndex < selectableOptionLabels.length; optionIndex++) {
|
|
120
119
|
const optionLabel = selectableOptionLabels[optionIndex];
|
|
121
120
|
const isCursorOption = optionIndex === cursorOptionIndex;
|
|
122
121
|
const isEditingThisOption = isNoteEditorOpen && isCursorOption;
|
|
123
|
-
const
|
|
122
|
+
const cursorPrefixText = isCursorOption ? "→ " : " ";
|
|
123
|
+
const cursorPrefix = isCursorOption ? theme.fg("accent", cursorPrefixText) : cursorPrefixText;
|
|
124
|
+
const bullet = isCursorOption ? "●" : "○";
|
|
125
|
+
const markerText = `${bullet} `;
|
|
126
|
+
const optionColor = isCursorOption ? "accent" : "text";
|
|
127
|
+
const prefixWidth = visibleWidth(cursorPrefixText) + visibleWidth(markerText);
|
|
128
|
+
const wrappedInlineLabelLines = buildWrappedOptionLabelWithInlineNote(
|
|
124
129
|
optionLabel,
|
|
125
130
|
getRawNoteForOption(optionIndex),
|
|
126
131
|
isEditingThisOption,
|
|
127
|
-
|
|
132
|
+
Math.max(1, width - prefixWidth),
|
|
133
|
+
INLINE_NOTE_WRAP_PADDING,
|
|
128
134
|
);
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
const
|
|
132
|
-
|
|
135
|
+
const continuationPrefix = " ".repeat(prefixWidth);
|
|
136
|
+
addLine(`${cursorPrefix}${theme.fg(optionColor, `${markerText}${wrappedInlineLabelLines[0] ?? ""}`)}`);
|
|
137
|
+
for (const wrappedLine of wrappedInlineLabelLines.slice(1)) {
|
|
138
|
+
addLine(`${continuationPrefix}${theme.fg(optionColor, wrappedLine)}`);
|
|
139
|
+
}
|
|
133
140
|
}
|
|
134
141
|
|
|
135
142
|
renderedLines.push("");
|
package/src/ask-tabs-ui.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExtensionUIContext } from "@mariozechner/pi-coding-agent";
|
|
2
|
-
import { Editor, type EditorTheme, Key, matchesKey, truncateToWidth } from "@mariozechner/pi-tui";
|
|
2
|
+
import { Editor, type EditorTheme, Key, matchesKey, truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
|
|
3
3
|
import {
|
|
4
4
|
OTHER_OPTION,
|
|
5
5
|
appendRecommendedTagToOptionLabels,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
type AskQuestion,
|
|
9
9
|
type AskSelection,
|
|
10
10
|
} from "./ask-logic";
|
|
11
|
-
import {
|
|
11
|
+
import { INLINE_NOTE_WRAP_PADDING, buildWrappedOptionLabelWithInlineNote } from "./ask-inline-note";
|
|
12
12
|
|
|
13
13
|
interface PreparedQuestion {
|
|
14
14
|
id: string;
|
|
@@ -317,27 +317,29 @@ export async function askQuestionsWithTabs(
|
|
|
317
317
|
addLine(theme.fg("text", ` ${preparedQuestion.question}`));
|
|
318
318
|
renderedLines.push("");
|
|
319
319
|
|
|
320
|
-
const maxInlineLabelLength = Math.max(12, width - 8);
|
|
321
320
|
for (let optionIndex = 0; optionIndex < preparedQuestion.options.length; optionIndex++) {
|
|
322
321
|
const optionLabel = preparedQuestion.options[optionIndex];
|
|
323
322
|
const isCursorOption = optionIndex === cursorOptionIndex;
|
|
324
323
|
const isOptionSelected = selectedOptionIndexes.includes(optionIndex);
|
|
325
324
|
const isEditingThisOption = isNoteEditorOpen && isCursorOption;
|
|
326
|
-
const
|
|
325
|
+
const cursorPrefixText = isCursorOption ? "→ " : " ";
|
|
326
|
+
const cursorPrefix = isCursorOption ? theme.fg("accent", cursorPrefixText) : cursorPrefixText;
|
|
327
|
+
const markerText = preparedQuestion.multi
|
|
328
|
+
? `${isOptionSelected ? "[x]" : "[ ]"} `
|
|
329
|
+
: `${isOptionSelected ? "●" : "○"} `;
|
|
330
|
+
const optionColor = isCursorOption ? "accent" : isOptionSelected ? "success" : "text";
|
|
331
|
+
const prefixWidth = visibleWidth(cursorPrefixText) + visibleWidth(markerText);
|
|
332
|
+
const wrappedInlineLabelLines = buildWrappedOptionLabelWithInlineNote(
|
|
327
333
|
optionLabel,
|
|
328
334
|
getQuestionNote(questionIndex, optionIndex),
|
|
329
335
|
isEditingThisOption,
|
|
330
|
-
|
|
336
|
+
Math.max(1, width - prefixWidth),
|
|
337
|
+
INLINE_NOTE_WRAP_PADDING,
|
|
331
338
|
);
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
addLine(`${cursorPrefix}${theme.fg(optionColor, `${checkbox} ${optionLabelWithInlineNote}`)}`);
|
|
337
|
-
} else {
|
|
338
|
-
const bullet = isOptionSelected ? "●" : "○";
|
|
339
|
-
const optionColor = isCursorOption ? "accent" : isOptionSelected ? "success" : "text";
|
|
340
|
-
addLine(`${cursorPrefix}${theme.fg(optionColor, `${bullet} ${optionLabelWithInlineNote}`)}`);
|
|
339
|
+
const continuationPrefix = " ".repeat(prefixWidth);
|
|
340
|
+
addLine(`${cursorPrefix}${theme.fg(optionColor, `${markerText}${wrappedInlineLabelLines[0] ?? ""}`)}`);
|
|
341
|
+
for (const wrappedLine of wrappedInlineLabelLines.slice(1)) {
|
|
342
|
+
addLine(`${continuationPrefix}${theme.fg(optionColor, wrappedLine)}`);
|
|
341
343
|
}
|
|
342
344
|
}
|
|
343
345
|
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import { Type, type Static } from "@sinclair/typebox";
|
|
3
|
-
import type
|
|
3
|
+
import { OTHER_OPTION, type AskQuestion } from "./ask-logic";
|
|
4
4
|
import { askSingleQuestionWithInlineNote } from "./ask-inline-ui";
|
|
5
5
|
import { askQuestionsWithTabs } from "./ask-tabs-ui";
|
|
6
6
|
|
|
@@ -37,6 +37,7 @@ interface QuestionResult {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
interface AskToolDetails {
|
|
40
|
+
id?: string;
|
|
40
41
|
question?: string;
|
|
41
42
|
options?: string[];
|
|
42
43
|
multi?: boolean;
|
|
@@ -45,16 +46,106 @@ interface AskToolDetails {
|
|
|
45
46
|
results?: QuestionResult[];
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
function sanitizeForSessionText(value: string): string {
|
|
50
|
+
return value
|
|
51
|
+
.replace(/[\r\n\t]/g, " ")
|
|
52
|
+
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "")
|
|
53
|
+
.replace(/\s{2,}/g, " ")
|
|
54
|
+
.trim();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function sanitizeOptionForSessionText(option: string): string {
|
|
58
|
+
const sanitizedOption = sanitizeForSessionText(option);
|
|
59
|
+
return sanitizedOption.length > 0 ? sanitizedOption : "(empty option)";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function toSessionSafeQuestionResult(result: QuestionResult): QuestionResult {
|
|
63
|
+
const selectedOptions = result.selectedOptions
|
|
64
|
+
.map((selectedOption) => sanitizeForSessionText(selectedOption))
|
|
65
|
+
.filter((selectedOption) => selectedOption.length > 0);
|
|
66
|
+
|
|
67
|
+
const rawCustomInput = result.customInput;
|
|
68
|
+
const customInput = rawCustomInput == null ? undefined : sanitizeForSessionText(rawCustomInput);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
id: sanitizeForSessionText(result.id) || "(unknown)",
|
|
72
|
+
question: sanitizeForSessionText(result.question) || "(empty question)",
|
|
73
|
+
options: result.options.map(sanitizeOptionForSessionText),
|
|
74
|
+
multi: result.multi,
|
|
75
|
+
selectedOptions,
|
|
76
|
+
customInput: customInput && customInput.length > 0 ? customInput : undefined,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function formatSelectionForSummary(result: QuestionResult): string {
|
|
81
|
+
const hasSelectedOptions = result.selectedOptions.length > 0;
|
|
82
|
+
const hasCustomInput = Boolean(result.customInput);
|
|
83
|
+
|
|
84
|
+
if (!hasSelectedOptions && !hasCustomInput) {
|
|
85
|
+
return "(cancelled)";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (hasSelectedOptions && hasCustomInput) {
|
|
89
|
+
const selectedPart = result.multi
|
|
90
|
+
? `[${result.selectedOptions.join(", ")}]`
|
|
91
|
+
: result.selectedOptions[0];
|
|
92
|
+
return `${selectedPart} + Other: "${result.customInput}"`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (hasCustomInput) {
|
|
96
|
+
return `"${result.customInput}"`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (result.multi) {
|
|
100
|
+
return `[${result.selectedOptions.join(", ")}]`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return result.selectedOptions[0];
|
|
104
|
+
}
|
|
105
|
+
|
|
48
106
|
function formatQuestionResult(result: QuestionResult): string {
|
|
49
|
-
|
|
50
|
-
|
|
107
|
+
return `${result.id}: ${formatSelectionForSummary(result)}`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function formatQuestionContext(result: QuestionResult, questionIndex: number): string {
|
|
111
|
+
const lines: string[] = [
|
|
112
|
+
`Question ${questionIndex + 1} (${result.id})`,
|
|
113
|
+
`Prompt: ${result.question}`,
|
|
114
|
+
"Options:",
|
|
115
|
+
...result.options.map((option, optionIndex) => ` ${optionIndex + 1}. ${option}`),
|
|
116
|
+
"Response:",
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
const hasSelectedOptions = result.selectedOptions.length > 0;
|
|
120
|
+
const hasCustomInput = Boolean(result.customInput);
|
|
121
|
+
|
|
122
|
+
if (!hasSelectedOptions && !hasCustomInput) {
|
|
123
|
+
lines.push(" Selected: (cancelled)");
|
|
124
|
+
return lines.join("\n");
|
|
51
125
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
126
|
+
|
|
127
|
+
if (hasSelectedOptions) {
|
|
128
|
+
const selectedText = result.multi
|
|
129
|
+
? `[${result.selectedOptions.join(", ")}]`
|
|
130
|
+
: result.selectedOptions[0];
|
|
131
|
+
lines.push(` Selected: ${selectedText}`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (hasCustomInput) {
|
|
135
|
+
if (!hasSelectedOptions) {
|
|
136
|
+
lines.push(` Selected: ${OTHER_OPTION}`);
|
|
137
|
+
}
|
|
138
|
+
lines.push(` Custom input: ${result.customInput}`);
|
|
56
139
|
}
|
|
57
|
-
|
|
140
|
+
|
|
141
|
+
return lines.join("\n");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function buildAskSessionContent(results: QuestionResult[]): string {
|
|
145
|
+
const safeResults = results.map(toSessionSafeQuestionResult);
|
|
146
|
+
const summaryLines = safeResults.map(formatQuestionResult).join("\n");
|
|
147
|
+
const contextBlocks = safeResults.map((result, index) => formatQuestionContext(result, index)).join("\n\n");
|
|
148
|
+
return `User answers:\n${summaryLines}\n\nAnswer context:\n${contextBlocks}`;
|
|
58
149
|
}
|
|
59
150
|
|
|
60
151
|
const ASK_TOOL_DESCRIPTION = `
|
|
@@ -96,7 +187,9 @@ export default function askExtension(pi: ExtensionAPI) {
|
|
|
96
187
|
? (await askQuestionsWithTabs(ctx.ui, [q as AskQuestion])).selections[0] ?? { selectedOptions: [] }
|
|
97
188
|
: await askSingleQuestionWithInlineNote(ctx.ui, q as AskQuestion);
|
|
98
189
|
const optionLabels = q.options.map((option) => option.label);
|
|
99
|
-
|
|
190
|
+
|
|
191
|
+
const result: QuestionResult = {
|
|
192
|
+
id: q.id,
|
|
100
193
|
question: q.question,
|
|
101
194
|
options: optionLabels,
|
|
102
195
|
multi: q.multi ?? false,
|
|
@@ -104,22 +197,18 @@ export default function askExtension(pi: ExtensionAPI) {
|
|
|
104
197
|
customInput: selection.customInput,
|
|
105
198
|
};
|
|
106
199
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
content: [{ type: "text", text: `User selected: ${selection.selectedOptions.join(", ")}` }],
|
|
117
|
-
details,
|
|
118
|
-
};
|
|
119
|
-
}
|
|
200
|
+
const details: AskToolDetails = {
|
|
201
|
+
id: q.id,
|
|
202
|
+
question: q.question,
|
|
203
|
+
options: optionLabels,
|
|
204
|
+
multi: q.multi ?? false,
|
|
205
|
+
selectedOptions: selection.selectedOptions,
|
|
206
|
+
customInput: selection.customInput,
|
|
207
|
+
results: [result],
|
|
208
|
+
};
|
|
120
209
|
|
|
121
210
|
return {
|
|
122
|
-
content: [{ type: "text", text:
|
|
211
|
+
content: [{ type: "text", text: buildAskSessionContent([result]) }],
|
|
123
212
|
details,
|
|
124
213
|
};
|
|
125
214
|
}
|
|
@@ -140,7 +229,7 @@ export default function askExtension(pi: ExtensionAPI) {
|
|
|
140
229
|
}
|
|
141
230
|
|
|
142
231
|
return {
|
|
143
|
-
content: [{ type: "text", text:
|
|
232
|
+
content: [{ type: "text", text: buildAskSessionContent(results) }],
|
|
144
233
|
details: { results } satisfies AskToolDetails,
|
|
145
234
|
};
|
|
146
235
|
},
|