mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-13 01:06:03 +00:00
feat: add in-product survey system (#2008)
* feat: add in-product survey system
- SurveyManager: event-based trigger, Space API communication
- Trigger on first successful non-WebSocket response
- Backend API: /api/v1/survey/{pending,respond,dismiss}
- Frontend: floating survey widget with progressive questions
- Flat radio/checkbox style (not dropdown Select)
* fix: persist triggered survey events to disk across restarts
Store triggered events in data/survey_triggered_events.json so that
restarting the process doesn't re-query Space for already-triggered events.
* fix: use metadata table for survey event persistence instead of file
Store triggered events in the existing metadata KV table
(key='survey_triggered_events') instead of a standalone JSON file.
* fix: ruff format and prettier fixes
This commit is contained in:
@@ -1007,4 +1007,50 @@ export class BackendClient extends BaseHttpClient {
|
||||
|
||||
return this.get(`/api/v1/monitoring/overview?${queryParams.toString()}`);
|
||||
}
|
||||
|
||||
// ============ Survey API ============
|
||||
public getSurveyPending(): Promise<{
|
||||
survey: {
|
||||
survey_id: string;
|
||||
version: number;
|
||||
title: Record<string, string>;
|
||||
description: Record<string, string>;
|
||||
questions: SurveyQuestion[];
|
||||
} | null;
|
||||
}> {
|
||||
return this.get('/api/v1/survey/pending');
|
||||
}
|
||||
|
||||
public submitSurveyResponse(
|
||||
surveyId: string,
|
||||
answers: Record<string, unknown>,
|
||||
completed: boolean = true,
|
||||
): Promise<object> {
|
||||
return this.post('/api/v1/survey/respond', {
|
||||
survey_id: surveyId,
|
||||
answers,
|
||||
completed,
|
||||
});
|
||||
}
|
||||
|
||||
public dismissSurvey(surveyId: string): Promise<object> {
|
||||
return this.post('/api/v1/survey/dismiss', { survey_id: surveyId });
|
||||
}
|
||||
}
|
||||
|
||||
export interface SurveyQuestion {
|
||||
id: string;
|
||||
type: 'single_select' | 'multi_select' | 'text';
|
||||
title: Record<string, string>;
|
||||
subtitle?: Record<string, string>;
|
||||
required: boolean;
|
||||
options?: SurveyOption[];
|
||||
placeholder?: Record<string, string>;
|
||||
max_length?: number;
|
||||
}
|
||||
|
||||
export interface SurveyOption {
|
||||
id: string;
|
||||
label: Record<string, string>;
|
||||
has_input?: boolean;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user