mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-10 05:13:17 +08:00
70 lines
2.4 KiB
JavaScript
70 lines
2.4 KiB
JavaScript
import { withSessionBindingLock } from './session-binding-lock.mjs';
|
|
|
|
export const WORKSPACE_SESSION_STALE = 'workspace-session-stale';
|
|
|
|
function workspaceSession(harness, sessionId) {
|
|
if (typeof harness.workspaceSession === 'function') {
|
|
return harness.workspaceSession(sessionId);
|
|
}
|
|
return Object.freeze({
|
|
sessionId,
|
|
sessionExists: (...args) => harness.sessionExists(sessionId, ...args),
|
|
models: (...args) => harness.getSessionModels(sessionId, ...args),
|
|
selectModel: (...args) => harness.selectSessionModel(sessionId, ...args),
|
|
isRunning: (...args) => harness.isSessionRunning(sessionId, ...args),
|
|
hasActiveTurn: (...args) => harness.hasActiveTurn(sessionId, ...args),
|
|
stopActiveTurn: (...args) => harness.stopActiveTurn(sessionId, ...args),
|
|
steerActiveTurn: (...args) => harness.steerActiveTurn(sessionId, ...args),
|
|
ask: (...args) => harness.ask(sessionId, ...args),
|
|
});
|
|
}
|
|
|
|
async function sessionExists(session, options) {
|
|
return options === undefined
|
|
? session.sessionExists()
|
|
: session.sessionExists(options);
|
|
}
|
|
|
|
async function createSession(harness, options) {
|
|
return options === undefined
|
|
? harness.createSession()
|
|
: harness.createSession(options);
|
|
}
|
|
|
|
/**
|
|
* Resolve, persist, and ask through a session that belongs to the bot's
|
|
* current workspace. A concurrent workspace switch invalidates the scoped
|
|
* session and retries before any prompt is sent to the stale session.
|
|
*/
|
|
export async function askInWorkspaceSession({
|
|
harness,
|
|
state,
|
|
key,
|
|
text,
|
|
content,
|
|
createOptions,
|
|
existsOptions,
|
|
askOptions,
|
|
}) {
|
|
while (true) {
|
|
try {
|
|
const binding = await withSessionBindingLock(state, key, async () => {
|
|
let sessionId = state.sessionFor(key);
|
|
let session = sessionId ? workspaceSession(harness, sessionId) : null;
|
|
if (!session || !(await sessionExists(session, existsOptions))) {
|
|
sessionId = await createSession(harness, createOptions);
|
|
if (await state.setSession(key, sessionId) === false) return null;
|
|
session = workspaceSession(harness, sessionId);
|
|
}
|
|
return { sessionId, session };
|
|
});
|
|
if (!binding) continue;
|
|
return {
|
|
sessionId: binding.sessionId,
|
|
answer: await binding.session.ask(content ?? text, askOptions),
|
|
};
|
|
} catch (error) {
|
|
if (error?.code !== WORKSPACE_SESSION_STALE) throw error;
|
|
}
|
|
}
|
|
}
|