support reasoning agentid by accountId or session for cron (#847)
This commit is contained in:
committed by
GitHub
Unverified
parent
54ec784545
commit
758a8f8c94
@@ -555,6 +555,25 @@ export async function listConfiguredAgentIds(): Promise<string[]> {
|
||||
return ids.length > 0 ? ids : [MAIN_AGENT_ID];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve agentId from channel and accountId using bindings.
|
||||
* Returns the agentId if found, or null if no binding exists.
|
||||
*/
|
||||
export async function resolveAgentIdFromChannel(channel: string, accountId?: string): Promise<string | null> {
|
||||
const config = await readOpenClawConfig() as AgentConfigDocument;
|
||||
const { channelToAgent, accountToAgent } = getChannelBindingMap(config.bindings);
|
||||
|
||||
// First try account-specific binding
|
||||
if (accountId) {
|
||||
const agentId = accountToAgent.get(`${channel}:${accountId}`);
|
||||
if (agentId) return agentId;
|
||||
}
|
||||
|
||||
// Fallback to channel-only binding
|
||||
const agentId = channelToAgent.get(channel);
|
||||
return agentId ?? null;
|
||||
}
|
||||
|
||||
export async function createAgent(
|
||||
name: string,
|
||||
options?: { inheritWorkspace?: boolean },
|
||||
|
||||
79
electron/utils/session-util.ts
Normal file
79
electron/utils/session-util.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Shared session utilities
|
||||
*/
|
||||
import { readFile, readdir } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { getOpenClawConfigDir } from './paths';
|
||||
|
||||
type JsonRecord = Record<string, unknown>;
|
||||
|
||||
/**
|
||||
* Parse sessions.json supporting both formats:
|
||||
* - Object-keyed: { "agent:xxx:yyy": { deliveryContext: {...} } }
|
||||
* - Array format: { sessions: [...] }
|
||||
*/
|
||||
export function extractSessionRecords(store: JsonRecord): JsonRecord[] {
|
||||
const directEntries = Object.entries(store)
|
||||
.filter(([key, value]) => key !== 'sessions' && value && typeof value === 'object')
|
||||
.map(([, value]) => value as JsonRecord);
|
||||
const arrayEntries = Array.isArray(store.sessions)
|
||||
? store.sessions.filter((entry): entry is JsonRecord => Boolean(entry && typeof entry === 'object'))
|
||||
: [];
|
||||
return [...directEntries, ...arrayEntries];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find accountId from session history by "to" address and channel type.
|
||||
* Searches all agent session directories for a matching deliveryContext.
|
||||
*/
|
||||
export async function resolveAccountIdFromSessionHistory(
|
||||
toAddress: string,
|
||||
channelType: string,
|
||||
): Promise<string | null> {
|
||||
const agentsDir = join(getOpenClawConfigDir(), 'agents');
|
||||
|
||||
let agentDirs: Array<{ name: string; isDirectory: () => boolean }>;
|
||||
try {
|
||||
agentDirs = await readdir(agentsDir, { withFileTypes: true });
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (const entry of agentDirs) {
|
||||
if (!entry.isDirectory()) continue;
|
||||
|
||||
const sessionsPath = join(agentsDir, entry.name, 'sessions', 'sessions.json');
|
||||
let raw: string;
|
||||
try {
|
||||
raw = await readFile(sessionsPath, 'utf8');
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!raw.trim()) continue;
|
||||
|
||||
let parsed: Record<string, unknown>;
|
||||
try {
|
||||
parsed = JSON.parse(raw);
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const session of extractSessionRecords(parsed as JsonRecord)) {
|
||||
const deliveryContext = session.deliveryContext as Record<string, unknown> | undefined;
|
||||
if (
|
||||
deliveryContext &&
|
||||
typeof deliveryContext.to === 'string' &&
|
||||
deliveryContext.to === toAddress &&
|
||||
typeof deliveryContext.channel === 'string' &&
|
||||
deliveryContext.channel === channelType
|
||||
) {
|
||||
if (typeof deliveryContext.accountId === 'string') {
|
||||
return deliveryContext.accountId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user