basic undo feature (#1268)

Co-authored-by: adamdotdevin <2363879+adamdottv@users.noreply.github.com>
Co-authored-by: Jay V <air@live.ca>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: Andrew Joslin <andrew@ajoslin.com>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Tobias Walle <9933601+tobias-walle@users.noreply.github.com>
This commit is contained in:
Dax
2025-07-23 20:30:46 -04:00
committed by GitHub
parent 507c975e92
commit 96866e52ce
26 changed files with 768 additions and 127 deletions

View File

@@ -1,4 +1,4 @@
configured_endpoints: 24
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-9574184bd9e916aa69eae8e26e0679556038d3fcfb4009a445c97c6cc3e4f3ee.yml
openapi_spec_hash: 93ba1215ab0dc853a1691b049cc47d75
config_hash: 09e4835d57ec7ed0b2d316c6815bcf0a
configured_endpoints: 26
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-1efc45c35b58e88b0550fbb0c7a204ef66522742f87c9e29c76a18b120c0d945.yml
openapi_spec_hash: 5e15d85e4704624f9b13bae1c71aa416
config_hash: 1ae82c93499b9f0b9ba828b8919f9cb3

View File

@@ -121,8 +121,10 @@ Methods:
- <code title="post /session/{id}/message">client.session.<a href="./src/resources/session.ts">chat</a>(id, { ...params }) -> AssistantMessage</code>
- <code title="post /session/{id}/init">client.session.<a href="./src/resources/session.ts">init</a>(id, { ...params }) -> SessionInitResponse</code>
- <code title="get /session/{id}/message">client.session.<a href="./src/resources/session.ts">messages</a>(id) -> SessionMessagesResponse</code>
- <code title="post /session/{id}/revert">client.session.<a href="./src/resources/session.ts">revert</a>(id, { ...params }) -> Session</code>
- <code title="post /session/{id}/share">client.session.<a href="./src/resources/session.ts">share</a>(id) -> Session</code>
- <code title="post /session/{id}/summarize">client.session.<a href="./src/resources/session.ts">summarize</a>(id, { ...params }) -> SessionSummarizeResponse</code>
- <code title="post /session/{id}/unrevert">client.session.<a href="./src/resources/session.ts">unrevert</a>(id) -> Session</code>
- <code title="delete /session/{id}/share">client.session.<a href="./src/resources/session.ts">unshare</a>(id) -> Session</code>
# Tui

View File

@@ -67,6 +67,7 @@ import {
SessionListResponse,
SessionMessagesResponse,
SessionResource,
SessionRevertParams,
SessionSummarizeParams,
SessionSummarizeResponse,
SnapshotPart,
@@ -846,6 +847,7 @@ export declare namespace Opencode {
type SessionSummarizeResponse as SessionSummarizeResponse,
type SessionChatParams as SessionChatParams,
type SessionInitParams as SessionInitParams,
type SessionRevertParams as SessionRevertParams,
type SessionSummarizeParams as SessionSummarizeParams,
};

View File

@@ -305,10 +305,20 @@ export interface KeybindsConfig {
messages_previous: string;
/**
* Revert message
* Redo message
*/
messages_redo: string;
/**
* @deprecated use messages_undo. Revert message
*/
messages_revert: string;
/**
* Undo message
*/
messages_undo: string;
/**
* List available models
*/

View File

@@ -71,6 +71,7 @@ export {
type SessionSummarizeResponse,
type SessionChatParams,
type SessionInitParams,
type SessionRevertParams,
type SessionSummarizeParams,
} from './session';
export {

View File

@@ -57,6 +57,13 @@ export class SessionResource extends APIResource {
return this._client.get(path`/session/${id}/message`, options);
}
/**
* Revert a message
*/
revert(id: string, body: SessionRevertParams, options?: RequestOptions): APIPromise<Session> {
return this._client.post(path`/session/${id}/revert`, { body, ...options });
}
/**
* Share a session
*/
@@ -75,6 +82,13 @@ export class SessionResource extends APIResource {
return this._client.post(path`/session/${id}/summarize`, { body, ...options });
}
/**
* Restore all reverted messages
*/
unrevert(id: string, options?: RequestOptions): APIPromise<Session> {
return this._client.post(path`/session/${id}/unrevert`, options);
}
/**
* Unshare the session
*/
@@ -231,7 +245,7 @@ export namespace Session {
export interface Revert {
messageID: string;
part: number;
partID?: string;
snapshot?: string;
}
@@ -513,6 +527,12 @@ export interface SessionInitParams {
providerID: string;
}
export interface SessionRevertParams {
messageID: string;
partID?: string;
}
export interface SessionSummarizeParams {
modelID: string;
@@ -550,6 +570,7 @@ export declare namespace SessionResource {
type SessionSummarizeResponse as SessionSummarizeResponse,
type SessionChatParams as SessionChatParams,
type SessionInitParams as SessionInitParams,
type SessionRevertParams as SessionRevertParams,
type SessionSummarizeParams as SessionSummarizeParams,
};
}

View File

@@ -118,6 +118,23 @@ describe('resource session', () => {
expect(dataAndResponse.response).toBe(rawResponse);
});
// skipped: tests are disabled for the time being
test.skip('revert: only required params', async () => {
const responsePromise = client.session.revert('id', { messageID: 'msg' });
const rawResponse = await responsePromise.asResponse();
expect(rawResponse).toBeInstanceOf(Response);
const response = await responsePromise;
expect(response).not.toBeInstanceOf(Response);
const dataAndResponse = await responsePromise.withResponse();
expect(dataAndResponse.data).toBe(response);
expect(dataAndResponse.response).toBe(rawResponse);
});
// skipped: tests are disabled for the time being
test.skip('revert: required and optional params', async () => {
const response = await client.session.revert('id', { messageID: 'msg', partID: 'prt' });
});
// skipped: tests are disabled for the time being
test.skip('share', async () => {
const responsePromise = client.session.share('id');
@@ -147,6 +164,18 @@ describe('resource session', () => {
const response = await client.session.summarize('id', { modelID: 'modelID', providerID: 'providerID' });
});
// skipped: tests are disabled for the time being
test.skip('unrevert', async () => {
const responsePromise = client.session.unrevert('id');
const rawResponse = await responsePromise.asResponse();
expect(rawResponse).toBeInstanceOf(Response);
const response = await responsePromise;
expect(response).not.toBeInstanceOf(Response);
const dataAndResponse = await responsePromise.withResponse();
expect(dataAndResponse.data).toBe(response);
expect(dataAndResponse.response).toBe(rawResponse);
});
// skipped: tests are disabled for the time being
test.skip('unshare', async () => {
const responsePromise = client.session.unshare('id');