File size: 5,791 Bytes
68d7816 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | import type { GoalSnapshot } from '#/features/goal/types';
import type { SessionStatusResponse } from './sessionProtocol';
import { LifecycleScope } from '#/app/scopes';
import {
type IAgentScopeHandle,
type ISessionScopeHandle,
ScopeActivation,
registerScopedService,
} from '#/_base/di/scope';
import {
IInstantiationService,
type ServicesAccessor,
} from '#/_base/di/instantiation';
import { ISessionTokenCountingService } from '#/session/tokenCounting/sessionTokenCounting';
import { IAgentGoalService } from '#/features/goal/goalService';
import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode';
import { IAgentPlanService } from '#/features/plan/plan';
import { IAgentProfileService } from '#/agent/profile/profile';
import { IAgentSwarmService } from '#/features/swarm/agent/swarm';
import { IAgentTowerService } from '#/features/tower/tower';
import { agentContextOf } from '#/agent/scopeContext/scopeContext';
import {
getLiveSessionById,
resumeSessionById,
} from '#/app/sessionManager/sessionLookup';
import { IModelCatalog } from '#/llm-adapter/model/catalog';
import { IModelService } from '#/llm-adapter/model/model';
import { ErrorCodes, Error2 } from '#/errors';
import { ensureMainAgent } from '#/session/agentLifecycle/mainAgent';
import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle';
import { IAgentLoopService } from '#/agent/loop/loop';
import { IAgentTaskService } from '#/agent/task/task';
import { IAgentFullCompactionService } from '#/agent/fullCompaction/fullCompaction';
import { ISessionLegacyService } from './sessionLegacy';
export class SessionLegacyService implements ISessionLegacyService {
declare readonly _serviceBrand: undefined;
private readonly services: ServicesAccessor;
constructor(@IInstantiationService instantiation: IInstantiationService) {
this.services = {
get: (id) => instantiation.invokeFunction((accessor) => accessor.get(id)),
};
}
private resume(sessionId: string): Promise<ISessionScopeHandle | undefined> {
return resumeSessionById(this.services, sessionId);
}
private async resolveMainAgent(sessionId: string): Promise<IAgentScopeHandle> {
const session = await this.resume(sessionId);
if (session === undefined) {
throw new Error2(ErrorCodes.SESSION_NOT_FOUND, `session ${sessionId} does not exist`);
}
const context = await ensureMainAgent(session);
const handle = session.accessor.get(IAgentLifecycleService).handleOf(context.agentId);
if (handle === undefined) {
throw new Error2(ErrorCodes.AGENT_NOT_FOUND, 'Main agent was not found');
}
return handle;
}
async status(sessionId: string): Promise<SessionStatusResponse> {
const agent = await this.resolveMainAgent(sessionId);
return this.assembleStatus(sessionId, agent);
}
private async assembleStatus(
sessionId: string,
agent: IAgentScopeHandle,
): Promise<SessionStatusResponse> {
const profile = agent.accessor.get(IAgentProfileService);
const tokenCounting = agent.accessor.get(ISessionTokenCountingService);
const permission = agent.accessor.get(IAgentPermissionModeService);
const plan = agent.accessor.get(IAgentPlanService);
const swarm = agent.accessor.get(IAgentSwarmService);
const tower = agent.accessor.get(IAgentTowerService);
const model = profile.getModel();
const capabilities = profile.getModelCapabilities();
let maxTokens = capabilities.max_input_tokens ?? capabilities.max_context_tokens;
if (maxTokens === 0 && model === '') {
maxTokens = resolveDefaultModelContextTokens(agent) ?? 0;
}
const tokens = tokenCounting.statusSize(agentContextOf(agent));
const planData = await plan.status();
return {
busy: this.readBusy(sessionId),
model: model === '' ? undefined : model,
thinking_level: model === '' ? '' : profile.getEffectiveThinkingLevel(),
permission: permission.mode,
plan_mode: planData !== null,
swarm_mode: swarm.isActive,
tower_mode: tower.isActive,
context_tokens: tokens,
max_context_tokens: maxTokens > 0 ? maxTokens : undefined,
context_usage: maxTokens > 0 ? Math.min(1, tokens / maxTokens) : undefined,
};
}
private readBusy(sessionId: string): boolean {
const handle = getLiveSessionById(this.services, sessionId);
if (handle === undefined) return false;
const agents = handle.accessor.get(IAgentLifecycleService);
for (const agent of agents.list()) {
const agentHandle = agents.handleOf(agent.agentId);
if (agentHandle === undefined) continue;
if (agentHandle.accessor.get(IAgentLoopService).snapshot().state === 'running') return true;
const tasks = agentHandle.accessor.get(IAgentTaskService);
if (tasks.list(true).length > 0) return true;
if (agentHandle.accessor.get(IAgentFullCompactionService).compacting !== null) return true;
}
return false;
}
async goal(sessionId: string): Promise<GoalSnapshot | null> {
const agent = await this.resolveMainAgent(sessionId);
return agent.accessor.get(IAgentGoalService).getGoal().goal;
}
}
function resolveDefaultModelContextTokens(agent: IAgentScopeHandle): number | undefined {
const defaultModel = agent.accessor.get(IModelService).getDefaultModel();
if (defaultModel === undefined || defaultModel.length === 0) return undefined;
try {
const capabilities = agent.accessor.get(IModelCatalog).get(defaultModel).capabilities;
return capabilities.max_input_tokens ?? capabilities.max_context_tokens;
} catch {
return undefined;
}
}
registerScopedService(
LifecycleScope.App,
ISessionLegacyService,
SessionLegacyService,
ScopeActivation.OnScopeCreated,
'sessionLegacy',
);
|