Open tanepiper opened 3 months ago
Hi, this topic was brought up here #1487 too. I'm currently leaning on leaving this up to custom prompts - but I'll consider any concrete proposal.
What would you like the API to look like? Some pseudo code of what the API could look like would be useful.
I'm going to have a go at this. Config for the prompt could include setting your pagination query params etc, I think. My use case is paginating calls to AWS services, not REST APIs, but I reckon they'd follow a similar approach?
Here's how I ended up re-writing my search app to work - as you can see when I go to previous or next pages I have to change the message (I also clear the screen and increase the size but that's a preference)
public async search(searchTerm?: string, page = 0) {
let message = 'Search for an Product Name';
if (searchTerm) {
message = `Search for an Product Name (Current: ${searchTerm})`;
}
const answer = await search<string>({
pageSize: page === 0 ? 5 : 10,
message,
theme: {
helpMode: 'always',
prefix: '🔍',
},
source: async (input: string, { signal }: { signal: AbortSignal }) => {
await setTimeout(1000);
if (signal?.aborted) return [];
if (!searchTerm && !input) {
return [];
}
// Return a promise that resolves after the debounce period
try {
const products = await this.client.itemsSearch(
input ?? searchTerm,
page,
50,
signal,
);
const results =
page > 0
? [
{
name: 'Previous Results',
value: `-${input ?? searchTerm}`,
description: 'Go to previous results page',
},
]
: [];
products?.forEach(({ content }, index) =>
results.push({
name: item.name,
value: item.id,
description: `Page: ${page + 1} | Record ${index + 1} / ${products.length} | ${content.id} `,
}),
);
if (products?.length === 50) {
results.push({
name: 'Next Results',
value: `+${input ?? searchTerm}`,
description: 'Select to load the next page',
});
}
return results;
} catch (error) {
console.error('\n Error during search:', error.message);
return [];
}
}
},
}).then((answer) => {
if (!isCorrectID(answer.split('-')?.[1])) {
page = answer[0] === '-' ? page - 1 : page + 1;
process.stdout.write('\x1Bc');
return this.search(answer.substring(1), page);
}
return answer;
});
return answer;
}
Looking at the design I guess it would be best to provide it along with the answer. Maybe have it as options on the setup (to enable prev/next) and then in the response:
.then((answer, { prev, next }) => {
if (prev) {
return ....
}
})
Yes the user has to handle it, but you provide a hook into it.
The only other way I see it to make it event-based
Description:
I'm using search to implement a cli tool that allows you to pass a name, which is then queried against a product database. The API has a max request of 50 items, but will have more than 50 results so a page value can be passed.
It would be good to either have a
pagination
option that can allow the search to recall the method with new parameters but keep the search query.The other option I can see is if I provide my own value here to handle as an answer I can call the search function again, but to do this I would want to be able to pass in the original value to display.