-
-
Notifications
You must be signed in to change notification settings - Fork 164
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add continue generate support, fix some bug about third-party m…
…odels error response
- Loading branch information
1 parent
d4ebe3e
commit 9c5e3e5
Showing
18 changed files
with
824 additions
and
628 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { getConfigKey } from '@/config' | ||
import { getContext } from '@/context' | ||
import { InMemoryChatMessageHistory } from '@langchain/core/chat_history' | ||
import { type BaseMessage, type MessageContent } from '@langchain/core/messages' | ||
import { | ||
ChatPromptTemplate, | ||
HumanMessagePromptTemplate, | ||
MessagesPlaceholder | ||
} from '@langchain/core/prompts' | ||
import { RunnableWithMessageHistory } from '@langchain/core/runnables' | ||
import { ChatOpenAI } from '@langchain/openai' | ||
import * as vscode from 'vscode' | ||
|
||
export const sessionIdHistoriesMap: Record<string, InMemoryChatMessageHistory> = | ||
{} | ||
|
||
export const createOpenAIRunnable = async ( | ||
historyMessages: BaseMessage[] = [] | ||
) => { | ||
const isDev = getContext().extensionMode !== vscode.ExtensionMode.Production | ||
const openaiBaseUrl = await getConfigKey('openaiBaseUrl') | ||
const openaiKey = await getConfigKey('openaiKey') | ||
const openaiModel = await getConfigKey('openaiModel') | ||
|
||
const model = new ChatOpenAI({ | ||
apiKey: openaiKey, | ||
configuration: { | ||
baseURL: openaiBaseUrl, | ||
fetch | ||
}, | ||
model: openaiModel, | ||
temperature: 0.95, // never use 1.0, some models do not support it | ||
verbose: isDev | ||
}) | ||
|
||
// some third-party language models are not compatible with the openAI specification, | ||
// they do not support some parameters, and langchain takes the initiative to add these parameters, | ||
// resulting in request failure, so here you need to clear these parameters | ||
model.frequencyPenalty = undefined as any | ||
model.n = undefined as any | ||
model.presencePenalty = undefined as any | ||
model.topP = undefined as any | ||
|
||
const prompt = ChatPromptTemplate.fromMessages([ | ||
new MessagesPlaceholder('history'), | ||
HumanMessagePromptTemplate.fromTemplate('{input}') | ||
]) | ||
|
||
const chain = prompt.pipe(model) | ||
|
||
const withMessageHistory = new RunnableWithMessageHistory({ | ||
runnable: chain, | ||
getMessageHistory: async sessionId => { | ||
if (sessionIdHistoriesMap[sessionId] === undefined) { | ||
const messageHistory = new InMemoryChatMessageHistory() | ||
|
||
if (historyMessages.length > 0) { | ||
await messageHistory.addMessages(historyMessages) | ||
} | ||
|
||
sessionIdHistoriesMap[sessionId] = messageHistory | ||
} | ||
|
||
return sessionIdHistoriesMap[sessionId]! | ||
}, | ||
inputMessagesKey: 'input', | ||
historyMessagesKey: 'history' | ||
}) | ||
|
||
return withMessageHistory | ||
} | ||
|
||
export const openaiAnswerContentToText = (content: MessageContent): string => { | ||
if (typeof content === 'string') return content | ||
|
||
return content | ||
.map(c => { | ||
if (c.type === 'text') return c.text | ||
return '' | ||
}) | ||
.join('') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { | ||
createTmpFileAndWriter, | ||
type CreateTmpFileOptions | ||
} from '@/create-tmp-file' | ||
import { | ||
removeCodeBlockEndSyntax, | ||
removeCodeBlockStartSyntax, | ||
removeCodeBlockSyntax | ||
} from '@/utils' | ||
import type { IterableReadableStream } from '@langchain/core/dist/utils/stream' | ||
import type { AIMessageChunk } from '@langchain/core/messages' | ||
|
||
import { openaiAnswerContentToText } from './llm' | ||
|
||
export interface TmpFileWriterOptions extends CreateTmpFileOptions { | ||
buildAiStream: () => Promise<IterableReadableStream<AIMessageChunk>> | ||
} | ||
|
||
export const tmpFileWriter = async (options: TmpFileWriterOptions) => { | ||
const { buildAiStream, ...createTmpFileOptions } = options | ||
|
||
const { writeTextPart, getText, writeText, isClosedWithoutSaving } = | ||
await createTmpFileAndWriter(createTmpFileOptions) | ||
|
||
const aiStream = await buildAiStream() | ||
for await (const chunk of aiStream) { | ||
if (isClosedWithoutSaving()) return | ||
|
||
// convert openai answer content to text | ||
const text = openaiAnswerContentToText(chunk.content) | ||
await writeTextPart(text) | ||
|
||
// remove code block syntax | ||
// for example, remove ```python\n and \n``` | ||
const currentCode = getText() | ||
const removeCodeBlockStartSyntaxCode = | ||
removeCodeBlockStartSyntax(currentCode) | ||
|
||
if (removeCodeBlockStartSyntaxCode !== currentCode) { | ||
await writeText(removeCodeBlockStartSyntaxCode) | ||
} | ||
} | ||
|
||
// remove code block end syntax | ||
// for example, remove \n``` at the end | ||
const currentCode = getText() | ||
const removeCodeBlockEndSyntaxCode = removeCodeBlockEndSyntax(currentCode) | ||
|
||
if (removeCodeBlockEndSyntaxCode !== currentCode) { | ||
await writeText(removeCodeBlockEndSyntaxCode) | ||
} | ||
|
||
// remove code block syntax | ||
// for example, remove ```python\n and \n``` at the start and end | ||
// just confirm the code is clean | ||
const finalCode = removeCodeBlockSyntax(getText()) | ||
|
||
// write the final code | ||
await writeText(finalCode) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import * as vscode from 'vscode' | ||
|
||
import { cleanupCodeConvertRunnables } from './commands/code-convert' | ||
import { cleanupCodeViewerHelperRunnables } from './commands/code-viewer-helper' | ||
|
||
export const cleanup = async (context: vscode.ExtensionContext) => { | ||
context.subscriptions.push( | ||
vscode.workspace.onDidCloseTextDocument(() => { | ||
cleanupCodeConvertRunnables() | ||
cleanupCodeViewerHelperRunnables() | ||
}) | ||
) | ||
} |
Oops, something went wrong.