Skip to content

Commit 3be6f6a

Browse files
committed
feat: support waylaidwanderer self-hosted api (#182)
1 parent 2ff0fee commit 3be6f6a

File tree

6 files changed

+116
-23
lines changed

6 files changed

+116
-23
lines changed

src/background/apis/bing-web.mjs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ export async function generateAnswersWithBingWebApi(port, question, session, acc
2424
answer = answer.replaceAll(/\[\^\d+\^\]/g, '')
2525
port.postMessage({ answer: answer, done: false, session: null })
2626
},
27-
...(session.bingWeb.conversationId
27+
...(session.bingWeb_conversationId
2828
? {
29-
conversationId: session.bingWeb.conversationId,
30-
conversationSignature: session.bingWeb.conversationSignature,
31-
clientId: session.bingWeb.clientId,
32-
invocationId: session.bingWeb.invocationId,
29+
conversationId: session.bingWeb_conversationId,
30+
conversationSignature: session.bingWeb_conversationSignature,
31+
clientId: session.bingWeb_clientId,
32+
invocationId: session.bingWeb_invocationId,
3333
}
3434
: {}),
3535
})
@@ -38,10 +38,10 @@ export async function generateAnswersWithBingWebApi(port, question, session, acc
3838
throw err
3939
})
4040

41-
session.bingWeb.conversationSignature = response.conversationSignature
42-
session.bingWeb.conversationId = response.conversationId
43-
session.bingWeb.clientId = response.clientId
44-
session.bingWeb.invocationId = response.invocationId
41+
session.bingWeb_conversationSignature = response.conversationSignature
42+
session.bingWeb_conversationId = response.conversationId
43+
session.bingWeb_clientId = response.clientId
44+
session.bingWeb_invocationId = response.invocationId
4545

4646
pushRecord(session, question, answer)
4747
console.debug('conversation history', { content: session.conversationRecords })
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { pushRecord, setAbortController } from './shared.mjs'
2+
import { getUserConfig } from '../../config/index.mjs'
3+
import { fetchSSE } from '../../utils/fetch-sse'
4+
import { isEmpty } from 'lodash-es'
5+
6+
/**
7+
* @param {Runtime.Port} port
8+
* @param {string} question
9+
* @param {Session} session
10+
*/
11+
export async function generateAnswersWithWaylaidwandererApi(port, question, session) {
12+
const { controller, messageListener } = setAbortController(port)
13+
14+
const config = await getUserConfig()
15+
16+
let answer = ''
17+
await fetchSSE(config.githubThirdPartyUrl, {
18+
method: 'POST',
19+
signal: controller.signal,
20+
headers: {
21+
'Content-Type': 'application/json',
22+
},
23+
body: JSON.stringify({
24+
message: question,
25+
stream: true,
26+
...(session.bingWeb_conversationId && {
27+
conversationId: session.bingWeb_conversationId,
28+
conversationSignature: session.bingWeb_conversationSignature,
29+
clientId: session.bingWeb_clientId,
30+
invocationId: session.bingWeb_invocationId,
31+
}),
32+
...(session.conversationId && {
33+
conversationId: session.conversationId,
34+
parentMessageId: session.parentMessageId,
35+
}),
36+
}),
37+
onMessage(message) {
38+
console.debug('sse message', message)
39+
if (message === '[DONE]') {
40+
pushRecord(session, question, answer)
41+
console.debug('conversation history', { content: session.conversationRecords })
42+
port.postMessage({ answer: null, done: true, session: session })
43+
return
44+
}
45+
let data
46+
try {
47+
data = JSON.parse(message)
48+
} catch (error) {
49+
console.debug('json error', error)
50+
return
51+
}
52+
if (data.conversationId) session.conversationId = data.conversationId
53+
if (data.parentMessageId) session.parentMessageId = data.parentMessageId
54+
if (data.conversationSignature)
55+
session.bingWeb_conversationSignature = data.conversationSignature
56+
if (data.conversationId) session.bingWeb_conversationId = data.conversationId
57+
if (data.clientId) session.bingWeb_clientId = data.clientId
58+
if (data.invocationId) session.bingWeb_invocationId = data.invocationId
59+
60+
if (typeof data === 'string') {
61+
answer += data
62+
port.postMessage({ answer: answer, done: false, session: null })
63+
}
64+
},
65+
async onStart() {},
66+
async onEnd() {
67+
port.onMessage.removeListener(messageListener)
68+
},
69+
async onError(resp) {
70+
port.onMessage.removeListener(messageListener)
71+
if (resp instanceof Error) throw resp
72+
const error = await resp.json().catch(() => ({}))
73+
throw new Error(!isEmpty(error) ? JSON.stringify(error) : `${resp.status} ${resp.statusText}`)
74+
},
75+
})
76+
}

src/background/index.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from './apis/openai-api'
1313
import { generateAnswersWithCustomApi } from './apis/custom-api.mjs'
1414
import { generateAnswersWithAzureOpenaiApi } from './apis/azure-openai-api.mjs'
15+
import { generateAnswersWithWaylaidwandererApi } from './apis/waylaidwanderer-api.mjs'
1516
import {
1617
azureOpenAiApiModelKeys,
1718
bingWebModelKeys,
@@ -21,6 +22,7 @@ import {
2122
defaultConfig,
2223
getPreferredLanguageKey,
2324
getUserConfig,
25+
githubThirdPartyApiModelKeys,
2426
gptApiModelKeys,
2527
Models,
2628
} from '../config/index.mjs'
@@ -110,6 +112,8 @@ Browser.runtime.onConnect.addListener((port) => {
110112
)
111113
} else if (azureOpenAiApiModelKeys.includes(session.modelName)) {
112114
await generateAnswersWithAzureOpenaiApi(port, session.question, session)
115+
} else if (githubThirdPartyApiModelKeys.includes(session.modelName)) {
116+
await generateAnswersWithWaylaidwandererApi(port, session.question, session)
113117
}
114118
} catch (err) {
115119
console.error(err)

src/config/index.mjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const Models = {
2020
gptApiDavinci: { value: 'text-davinci-003', desc: 'GPT-3.5' },
2121
customModel: { value: '', desc: 'Custom Model' },
2222
azureOpenAi: { value: '', desc: 'ChatGPT (Azure)' },
23+
waylaidwandererApi: { value: '', desc: 'Waylaidwanderer API (Github)' },
2324
}
2425

2526
export const chatgptWebModelKeys = ['chatgptFree35', 'chatgptPlus4']
@@ -28,6 +29,7 @@ export const gptApiModelKeys = ['gptApiDavinci']
2829
export const chatgptApiModelKeys = ['chatgptApi35', 'chatgptApi4_8k', 'chatgptApi4_32k']
2930
export const customApiModelKeys = ['customModel']
3031
export const azureOpenAiApiModelKeys = ['azureOpenAi']
32+
export const githubThirdPartyApiModelKeys = ['waylaidwandererApi']
3133

3234
export const TriggerMode = {
3335
always: 'Always',
@@ -77,6 +79,7 @@ export const defaultConfig = {
7779

7880
customModelApiUrl: 'http://localhost:8000/chat/completions',
7981
customModelName: 'llama-7b-int4',
82+
githubThirdPartyUrl: 'http://127.0.0.1:3000/conversation',
8083

8184
// advanced
8285

@@ -167,6 +170,10 @@ export function isUsingAzureOpenAi(configOrSession) {
167170
return azureOpenAiApiModelKeys.includes(configOrSession.modelName)
168171
}
169172

173+
export function isUsingGithubThirdPartyApi(configOrSession) {
174+
return githubThirdPartyApiModelKeys.includes(configOrSession.modelName)
175+
}
176+
170177
export async function getPreferredLanguageKey() {
171178
const config = await getUserConfig()
172179
if (config.preferredLanguage === 'auto') return config.userLanguage

src/popup/Popup.jsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
isUsingApiKey,
88
isUsingAzureOpenAi,
99
isUsingCustomModel,
10+
isUsingGithubThirdPartyApi,
1011
isUsingMultiModeModel,
1112
ModelMode,
1213
Models,
@@ -215,6 +216,17 @@ function GeneralPart({ config, updateConfig }) {
215216
}}
216217
/>
217218
)}
219+
{isUsingGithubThirdPartyApi(config) && (
220+
<input
221+
type="text"
222+
value={config.githubThirdPartyUrl}
223+
placeholder={t('API Url')}
224+
onChange={(e) => {
225+
const url = e.target.value
226+
updateConfig({ githubThirdPartyUrl: url })
227+
}}
228+
/>
229+
)}
218230
</label>
219231
<label>
220232
<legend>{t('Preferred Language')}</legend>

src/utils/init-session.mjs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
import { Models } from '../config/index.mjs'
22

3-
/**
4-
* @typedef {object} BingWeb
5-
* @property {string|null} conversationSignature
6-
* @property {string|null} conversationId
7-
* @property {string|null} clientId
8-
* @property {string|null} invocationId
9-
*/
103
/**
114
* @typedef {object} Session
125
* @property {string|null} question
@@ -20,7 +13,10 @@ import { Models } from '../config/index.mjs'
2013
* @property {string|null} conversationId - chatGPT web mode
2114
* @property {string|null} messageId - chatGPT web mode
2215
* @property {string|null} parentMessageId - chatGPT web mode
23-
* @property {BingWeb} bingWeb
16+
* @property {string|null} bingWeb_conversationSignature
17+
* @property {string|null} bingWeb_conversationId
18+
* @property {string|null} bingWeb_clientId
19+
* @property {string|null} bingWeb_invocationId
2420
*/
2521
/**
2622
* @param {string|null} question
@@ -57,11 +53,9 @@ export function initSession({
5753
parentMessageId: null,
5854

5955
// bing
60-
bingWeb: {
61-
conversationSignature: null,
62-
conversationId: null,
63-
clientId: null,
64-
invocationId: null,
65-
},
56+
bingWeb_conversationSignature: null,
57+
bingWeb_conversationId: null,
58+
bingWeb_clientId: null,
59+
bingWeb_invocationId: null,
6660
}
6761
}

0 commit comments

Comments
 (0)