|
|
@@ -369,6 +369,24 @@ export interface Config {
|
|
|
})[]
|
|
|
}
|
|
|
|
|
|
+/** Reject self-contained identity conflicts before any configured agent starts. */
|
|
|
+function validateConfiguredAgents(agents: Config['agents']): void {
|
|
|
+ const exactIdentities = new Map<SessionId, string>()
|
|
|
+ for (const { id, sessionId, resumeSessionId } of agents) {
|
|
|
+ const hasResumeId = resumeSessionId !== undefined && resumeSessionId !== ''
|
|
|
+ if (sessionId !== undefined && hasResumeId) {
|
|
|
+ throw new Error(`agent "${id}": sessionId and resumeSessionId are mutually exclusive`)
|
|
|
+ }
|
|
|
+ const exactIdentity = hasResumeId ? resumeSessionId : sessionId
|
|
|
+ if (exactIdentity === undefined) continue
|
|
|
+ const firstId = exactIdentities.get(exactIdentity)
|
|
|
+ if (firstId !== undefined) {
|
|
|
+ throw new Error(`agents "${firstId}" and "${id}" use duplicate exact session identity "${exactIdentity}"`)
|
|
|
+ }
|
|
|
+ exactIdentities.set(exactIdentity, id)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/** Concrete ReactLoopAgent factory and driver service. */
|
|
|
export class AgentLoop extends Service implements AgentFactory {
|
|
|
static inject = ['agents', 'sessions', 'llm', 'tools', 'systemPrompt']
|
|
|
@@ -390,6 +408,7 @@ export class AgentLoop extends Service implements AgentFactory {
|
|
|
|
|
|
constructor(ctx: Context, public config: Config) {
|
|
|
super(ctx, 'agentLoop')
|
|
|
+ validateConfiguredAgents(config.agents)
|
|
|
this.ownership = new FactoryOwnership(ctx.fiber)
|
|
|
this.runtime = { ctx }
|
|
|
ctx.effect(() => () => this.ownership.dispose(), 'agentLoop.transactions()')
|
|
|
@@ -412,9 +431,6 @@ export class AgentLoop extends Service implements AgentFactory {
|
|
|
}
|
|
|
continue
|
|
|
}
|
|
|
- if (sessionId !== undefined) {
|
|
|
- throw new Error(`agent "${id}": sessionId and resumeSessionId are mutually exclusive`)
|
|
|
- }
|
|
|
ctx.effect(() => {
|
|
|
const fiber = ctx.inject(['sessionPersistence'], (childCtx: Context) => {
|
|
|
void this.resumeWith(ctx, childCtx.sessionPersistence, {
|