Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 8x 8x 19x 8x 18x 18x 8x 8x 1x 7x 7x | import {
CopilotEmbeddedToolCall,
CopilotEmbeddedToolName,
} from '../copilot-embedded-tool-call/copilot-embedded-tool-call.model';
import { CopilotEmbeddedChoiceData } from './copilot-embedded-choice.interface';
import { CopilotEmbeddedChoice } from './copilot-embedded-choice.model';
const CHOICE_TOOL: CopilotEmbeddedToolName = 'PWA_ask_choice';
/** Accepts either a real array or a pipe-separated string (the resilient Flowise schema shape). */
function parseOptions(raw: unknown): string[] {
const values = Array.isArray(raw) ? raw : typeof raw === 'string' ? raw.split('|') : [];
return values.map(option => `${option}`.trim()).filter(Boolean);
}
export class CopilotEmbeddedChoiceMapper {
/**
* Maps the `PWA_ask_choice` signal tool call of a chatflow response to a choice prompt, so the PWA
* can render the options as clickable choice chips.
*
* @param tools The tool calls of a chatflow response (`usedTools`).
* @returns The choice prompt or `undefined` when the tool was not called or carries no usable options.
*/
static fromToolCalls(tools: CopilotEmbeddedToolCall[]): CopilotEmbeddedChoice {
const call = tools?.find(tool => tool?.tool === CHOICE_TOOL);
return call ? CopilotEmbeddedChoiceMapper.fromData(call.toolInput as CopilotEmbeddedChoiceData) : undefined;
}
private static fromData(data: CopilotEmbeddedChoiceData): CopilotEmbeddedChoice {
const options = parseOptions(data?.options);
if (!options.length) {
return;
}
const question = typeof data.question === 'string' ? data.question.trim() : undefined;
return {
question: question || undefined,
options,
multiSelect: data.multiSelect === true || data.multiSelect === 'true',
};
}
}
|