suggested questions endpoint backed by Gemini
This commit is contained in:
parent
e20120056a
commit
e30b01a3bb
|
|
@ -129,19 +129,49 @@ class UserProvider extends CoreProvier {
|
||||||
Future<String?> setAndGetToken({String? newToken}) async {
|
Future<String?> setAndGetToken({String? newToken}) async {
|
||||||
try {
|
try {
|
||||||
if (newToken == null) {
|
if (newToken == null) {
|
||||||
final cached = TokenStorage.accessToken;
|
// اگر access token معتبر است، همان را برمیگردانیم.
|
||||||
if (cached != null && cached.isNotEmpty) {
|
if (TokenStorage.isAccessTokenValid) {
|
||||||
RequestService.token = cached;
|
final cached = TokenStorage.accessToken;
|
||||||
return cached;
|
if (cached != null && cached.isNotEmpty) {
|
||||||
|
RequestService.token = cached;
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// access token منقضی است؛ اگر refresh token داریم، تلاش به
|
||||||
|
// refresh قبل از ادامه. اگر refresh هم fail شد، session را پاک
|
||||||
|
// میکنیم تا splash کاربر را به login بفرستد.
|
||||||
|
if (TokenStorage.refreshToken != null &&
|
||||||
|
TokenStorage.refreshToken!.isNotEmpty) {
|
||||||
|
final ok = await KeycloakAuthService.instance.refresh();
|
||||||
|
if (ok) {
|
||||||
|
final fresh = TokenStorage.accessToken;
|
||||||
|
if (fresh != null && fresh.isNotEmpty) {
|
||||||
|
RequestService.token = fresh;
|
||||||
|
await StorageService.setValue(key: 'token', value: fresh);
|
||||||
|
return fresh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// refresh fail کرد → session تمام شده، کاربر باید مجدد login کند.
|
||||||
|
print(
|
||||||
|
'🔐 setAndGetToken: refresh failed, clearing session for re-login');
|
||||||
|
await TokenStorage.clear();
|
||||||
|
await StorageService.delete(key: 'token');
|
||||||
|
RequestService.token = null;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// نه access معتبر داریم نه refresh — هیچ session فعالی نیست.
|
||||||
final token = await StorageService.getValue(key: 'token');
|
final token = await StorageService.getValue(key: 'token');
|
||||||
if (token != null) RequestService.token = token;
|
if (token != null && token.isNotEmpty) {
|
||||||
return token;
|
RequestService.token = token;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
RequestService.token = newToken;
|
RequestService.token = newToken;
|
||||||
await StorageService.setValue(key: 'token', value: newToken);
|
await StorageService.setValue(key: 'token', value: newToken);
|
||||||
return null;
|
return null;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
print('🔐 setAndGetToken error: $e');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -303,6 +303,6 @@ class RequestHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
static String aiSuggestedQuestions() {
|
static String aiSuggestedQuestions() {
|
||||||
return '$baseUrl/ai/aiquestion';
|
return '$newApiBaseUrl/ai/aiquestion';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -147,27 +147,22 @@ class _AiChatPageState extends State<AiChatPage> with TickerProviderStateMixin {
|
||||||
final bots = context.read<HistoryAiChatState>().bots;
|
final bots = context.read<HistoryAiChatState>().bots;
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_searchBot = bots.firstWhere((b) => b.id == 36);
|
// قبلاً _geminiBot از bot id=35 با name=gemini دنبال میشد
|
||||||
|
// (الگوی legacy multi-model). در ساختار جدید Gemini یک bot
|
||||||
|
// مستقل با id=36 است.
|
||||||
try {
|
try {
|
||||||
_geminiBot = bots.firstWhere((b) =>
|
_searchBot = bots.firstWhere((b) => b.id == 36);
|
||||||
b.id == 35 &&
|
} catch (_) {
|
||||||
(b.name?.toLowerCase().contains('gemini') ?? false));
|
_searchBot = null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
_geminiBot = bots.firstWhere(
|
||||||
|
(b) => (b.name?.toLowerCase().contains('gemini') ?? false));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_geminiBot = BotsModel(
|
_geminiBot = BotsModel(
|
||||||
id: 35,
|
id: 36,
|
||||||
name: 'Gemini',
|
name: 'gemini',
|
||||||
responseType: 'text',
|
responseType: 'text',
|
||||||
attachmentType: [
|
|
||||||
'audio',
|
|
||||||
'image',
|
|
||||||
'pdf',
|
|
||||||
'csv',
|
|
||||||
'doc',
|
|
||||||
'docx',
|
|
||||||
'xls',
|
|
||||||
'xlsx'
|
|
||||||
],
|
|
||||||
attachment: 1,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|
@ -883,15 +878,20 @@ class _AiChatPageState extends State<AiChatPage> with TickerProviderStateMixin {
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
AiMessageBar(
|
AiMessageBar(
|
||||||
bot: _isSearchMode && _searchBot != null
|
// قبلاً وقتی search mode روشن میشد bot به Gemini سویچ
|
||||||
? _searchBot!
|
// میشد (legacy). الان وبجستجو بهعنوان tool روی هر
|
||||||
: _getSelectedBot(),
|
// bot انتخابشده اعمال میشود؛ پس همان bot فعلی را
|
||||||
|
// پاس میدهیم.
|
||||||
|
bot: _getSelectedBot(),
|
||||||
attch: widget.args.attach,
|
attch: widget.args.attach,
|
||||||
assistantsName: widget.args.assistantsName,
|
assistantsName: widget.args.assistantsName,
|
||||||
showSearchToggle: _currentBot.id == 35 && _searchBot != null,
|
// toggle همیشه برای GPT/Gemini در دسترس باشد — نیازی
|
||||||
|
// به _searchBot (= bot 36) نیست چون tool روی هر bot
|
||||||
|
// فعال است.
|
||||||
|
showSearchToggle: _currentBot.id == 35 || _currentBot.id == 36,
|
||||||
isSearchMode: _isSearchMode,
|
isSearchMode: _isSearchMode,
|
||||||
onSearchModeToggled: (bool isSearchOn) {
|
onSearchModeToggled: (bool isSearchOn) {
|
||||||
if (_searchBot == null) return;
|
print('[SEARCH_TOGGLE] tapped — new mode=$isSearchOn');
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSearchMode = isSearchOn;
|
_isSearchMode = isSearchOn;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,7 @@ class AiChatState extends CoreProvier {
|
||||||
|
|
||||||
Future<void> postMessage(BotsModel bot, bool isAssistants,
|
Future<void> postMessage(BotsModel bot, bool isAssistants,
|
||||||
{bool webSearch = false}) async {
|
{bool webSearch = false}) async {
|
||||||
|
print('[POST_MSG] bot.id=${bot.id} bot.name=${bot.name} webSearch=$webSearch');
|
||||||
onResponsing = true;
|
onResponsing = true;
|
||||||
final uploadedFile = file;
|
final uploadedFile = file;
|
||||||
file = null;
|
file = null;
|
||||||
|
|
|
||||||
|
|
@ -794,7 +794,8 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
||||||
openAttach = false;
|
openAttach = false;
|
||||||
state.update();
|
state.update();
|
||||||
await state.postMessage(
|
await state.postMessage(
|
||||||
widget.bot, widget.assistantsName != null);
|
widget.bot, widget.assistantsName != null,
|
||||||
|
webSearch: widget.isSearchMode);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue