mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
checkpoint state improvements
This commit is contained in:
parent
8c26fd2081
commit
78671db5b8
4 changed files with 29 additions and 5 deletions
|
|
@ -358,9 +358,9 @@ class ChatThreadService extends Disposable implements IChatThreadService {
|
|||
else if (behavior === 'set') {
|
||||
this.streamState[threadId] = state
|
||||
}
|
||||
else throw new Error(`setStreamState`)
|
||||
}
|
||||
|
||||
|
||||
this._onDidChangeStreamState.fire({ threadId })
|
||||
}
|
||||
|
||||
|
|
@ -488,7 +488,6 @@ class ChatThreadService extends Disposable implements IChatThreadService {
|
|||
const displayContentSoFar = this.streamState[threadId]?.displayContentSoFar ?? ''
|
||||
const reasoningSoFar = this.streamState[threadId]?.reasoningSoFar ?? ''
|
||||
const toolCallSoFar = this.streamState[threadId]?.toolCallSoFar
|
||||
console.log('toolInProgress', toolCallSoFar)
|
||||
|
||||
const llmCancelToken = this.streamState[threadId]?.streamingToken
|
||||
if (llmCancelToken !== undefined) { this._llmMessageService.abort(llmCancelToken) }
|
||||
|
|
@ -498,6 +497,8 @@ class ChatThreadService extends Disposable implements IChatThreadService {
|
|||
if (toolCallSoFar) {
|
||||
this._addMessageToThread(threadId, { role: 'interrupted_streaming_tool', name: toolCallSoFar.name })
|
||||
}
|
||||
|
||||
this._addUserCheckpoint({ threadId })
|
||||
}
|
||||
|
||||
this._setStreamState(threadId, {}, 'set')
|
||||
|
|
@ -1089,14 +1090,21 @@ We only need to do it for files that were edited since `from`, ie files between
|
|||
if (!thread) return // should never happen
|
||||
|
||||
|
||||
const llmCancelToken = this.streamState[threadId]?.streamingToken // currently streaming LLM on this thread
|
||||
if (llmCancelToken === undefined && this.streamState[threadId]?.isRunning === 'LLM') {
|
||||
// if about to call the other LLM, just wait for it by stopping right now
|
||||
return
|
||||
}
|
||||
// stop it (this simply resolves the promise to free up space)
|
||||
if (llmCancelToken !== undefined) this._llmMessageService.abort(llmCancelToken)
|
||||
|
||||
|
||||
|
||||
// add dummy before this message to keep checkpoint before user message idea consistent
|
||||
if (thread.messages.length === 0) {
|
||||
this._addUserCheckpoint({ threadId })
|
||||
}
|
||||
|
||||
// if the current thread is already streaming, stop it (this simply resolves the promise to free up space)
|
||||
const llmCancelToken = this.streamState[threadId]?.streamingToken
|
||||
if (llmCancelToken !== undefined) this._llmMessageService.abort(llmCancelToken)
|
||||
|
||||
const { chatMode } = this._settingsService.state.globalSettings
|
||||
|
||||
|
|
@ -1488,6 +1496,10 @@ We only need to do it for files that were edited since `from`, ie files between
|
|||
}
|
||||
}
|
||||
}, true)
|
||||
|
||||
// when change focused message idx, jump
|
||||
if (messageIdx !== undefined)
|
||||
this.jumpToCheckpointBeforeMessageIdx({ threadId, messageIdx, jumpToUserModified: true })
|
||||
}
|
||||
|
||||
// set message.state
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ export const VoidInputBox2 = forwardRef<HTMLTextAreaElement, InputBox2Props>(fun
|
|||
|
||||
return (
|
||||
<textarea
|
||||
autoFocus={false}
|
||||
ref={useCallback((r: HTMLTextAreaElement | null) => {
|
||||
if (fnsRef)
|
||||
fnsRef.current = fns
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { ITextModel } from '../../../../editor/common/model.js';
|
|||
import { IResolvedTextEditorModel, ITextModelService } from '../../../../editor/common/services/resolverService.js';
|
||||
import { registerSingleton, InstantiationType } from '../../../../platform/instantiation/common/extensions.js';
|
||||
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { ITextFileService } from '../../../services/textfile/common/textfiles.js';
|
||||
|
||||
type VoidModelType = {
|
||||
model: ITextModel | null;
|
||||
|
|
@ -16,6 +17,8 @@ export interface IVoidModelService {
|
|||
getModel(uri: URI): VoidModelType;
|
||||
getModelFromFsPath(fsPath: string): VoidModelType;
|
||||
getModelSafe(uri: URI): Promise<VoidModelType>;
|
||||
saveModel(uri: URI): Promise<void>;
|
||||
|
||||
}
|
||||
|
||||
export const IVoidModelService = createDecorator<IVoidModelService>('voidVoidModelService');
|
||||
|
|
@ -27,10 +30,17 @@ class VoidModelService extends Disposable implements IVoidModelService {
|
|||
|
||||
constructor(
|
||||
@ITextModelService private readonly _textModelService: ITextModelService,
|
||||
@ITextFileService private readonly _textFileService: ITextFileService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
saveModel = async (uri: URI) => {
|
||||
await this._textFileService.save(uri, { // we want [our change] -> [save] so it's all treated as one change.
|
||||
skipSaveParticipants: true // avoid triggering extensions etc (if they reformat the page, it will add another item to the undo stack)
|
||||
})
|
||||
}
|
||||
|
||||
initializeModel = async (uri: URI) => {
|
||||
if (uri.fsPath in this._modelRefOfURI) return;
|
||||
const editorModelRef = await this._textModelService.createModelReference(uri);
|
||||
|
|
|
|||
|
|
@ -284,6 +284,7 @@ export const extractToolsWrapper = (
|
|||
|
||||
parser.write(newText)
|
||||
|
||||
// firstToolCallRef.current === state.currentToolCall is always true
|
||||
onText({
|
||||
...params,
|
||||
fullText,
|
||||
|
|
|
|||
Loading…
Reference in a new issue