Fix: Web Services Improvement

Fix: Web Services Improvement
This commit is contained in:
Dinh Long Nguyen 2025-09-15 09:08:30 +07:00 committed by GitHub
parent 596930174f
commit 0771b998a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 29 additions and 33 deletions

View File

@ -3,7 +3,7 @@
* Handles API requests to Jan backend for models and chat completions
*/
import { JanAuthService } from '../shared/auth'
import { getSharedAuthService, JanAuthService } from '../shared'
import { JanModel, janProviderStore } from './store'
// JAN_API_BASE is defined in vite.config.ts
@ -77,7 +77,7 @@ export class JanApiClient {
private authService: JanAuthService
private constructor() {
this.authService = JanAuthService.getInstance()
this.authService = getSharedAuthService()
}
static getInstance(): JanApiClient {
@ -216,12 +216,9 @@ export class JanApiClient {
async initialize(): Promise<void> {
try {
await this.authService.initialize()
janProviderStore.setAuthenticated(true)
// Fetch initial models
await this.getModels()
console.log('Jan API client initialized successfully')
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Failed to initialize API client'

View File

@ -5,7 +5,7 @@
*/
import { MCPExtension, MCPTool, MCPToolCallResult } from '@janhq/core'
import { JanAuthService } from '../shared/auth'
import { getSharedAuthService, JanAuthService } from '../shared'
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
import { JanMCPOAuthProvider } from './oauth-provider'
@ -30,14 +30,12 @@ export default class MCPExtensionWeb extends MCPExtension {
version?: string
) {
super(url, name, productName, active, description, version)
this.authService = JanAuthService.getInstance()
this.authService = getSharedAuthService()
this.oauthProvider = new JanMCPOAuthProvider(this.authService)
}
async onLoad(): Promise<void> {
try {
// Initialize authentication first
await this.authService.initialize()
// Initialize MCP client with OAuth
await this.initializeMCPClient()
// Then fetch tools

View File

@ -20,21 +20,13 @@ const AUTH_STORAGE_KEY = 'jan_auth_tokens'
const TOKEN_EXPIRY_BUFFER = 60 * 1000 // 1 minute buffer before actual expiry
export class JanAuthService {
private static instance: JanAuthService
private tokens: AuthTokens | null = null
private tokenExpiryTime: number = 0
private constructor() {
constructor() {
this.loadTokensFromStorage()
}
static getInstance(): JanAuthService {
if (!JanAuthService.instance) {
JanAuthService.instance = new JanAuthService()
}
return JanAuthService.instance
}
private loadTokensFromStorage(): void {
try {
const storedTokens = localStorage.getItem(AUTH_STORAGE_KEY)
@ -169,16 +161,6 @@ export class JanAuthService {
return this.tokens.access_token
}
async initialize(): Promise<void> {
try {
await this.getValidAccessToken()
console.log('Jan auth service initialized successfully')
} catch (error) {
console.error('Failed to initialize Jan auth service:', error)
throw error
}
}
async getAuthHeader(): Promise<{ Authorization: string }> {
const token = await this.getValidAccessToken()
return {
@ -217,4 +199,21 @@ export class JanAuthService {
logout(): void {
this.clearTokens()
}
}
declare global {
interface Window {
janAuthService?: JanAuthService
}
}
/**
* Gets or creates the shared JanAuthService instance on the window object
* This ensures all extensions use the same auth service instance
*/
export function getSharedAuthService(): JanAuthService {
if (!window.janAuthService) {
window.janAuthService = new JanAuthService()
}
return window.janAuthService
}

View File

@ -1,3 +1,3 @@
export { getSharedDB } from './db'
export { JanAuthService } from './auth'
export { JanAuthService, getSharedAuthService } from './auth'
export type { AuthTokens, AuthResponse } from './auth'

View File

@ -193,6 +193,7 @@ export const sendCompletion = async (
if (
thread.model.id &&
models[providerName]?.models !== true && // Skip if provider accepts any model (models: true)
!Object.values(models[providerName]).flat().includes(thread.model.id) &&
!tokenJS.extendedModelExist(providerName as any, thread.model.id) &&
provider.provider !== 'llamacpp'
@ -396,9 +397,12 @@ export const postMessageProcessing = async (
let toolParameters = {}
if (toolCall.function.arguments.length) {
try {
console.log('Raw tool arguments:', toolCall.function.arguments)
toolParameters = JSON.parse(toolCall.function.arguments)
console.log('Parsed tool parameters:', toolParameters)
} catch (error) {
console.error('Failed to parse tool arguments:', error)
console.error('Raw arguments that failed:', toolCall.function.arguments)
}
}
const approved =
@ -414,9 +418,7 @@ export const postMessageProcessing = async (
const { promise, cancel } = getServiceHub().mcp().callToolWithCancellation({
toolName: toolCall.function.name,
arguments: toolCall.function.arguments.length
? JSON.parse(toolCall.function.arguments)
: {},
arguments: toolCall.function.arguments.length ? toolParameters : {},
})
useAppState.getState().setCancelToolCall(cancel)

View File

@ -114,7 +114,7 @@ const AppLayout = () => {
{/* Fake absolute panel top to enable window drag */}
<div className="absolute w-full h-10 z-10" data-tauri-drag-region />
<DialogAppUpdater />
<BackendUpdater />
{PlatformFeatures[PlatformFeature.LOCAL_INFERENCE] && <BackendUpdater />}
{/* Use ResizablePanelGroup only on larger screens */}
{!isSmallScreen && isLeftPanelOpen ? (