fix(agent): pass sessionId to system prompt for text chat OAuth trigger
Text sessions were not passing sessionId to SystemPromptBuilder, causing Claude to use the `initiate_dingtalk_binding` custom tool (claude_api only). When the engine is claude_agent_sdk, this tool does not exist → 404. Fix: pass session.id as sessionId to systemPromptBuilder.build() in agent.controller.ts. Claude will now use the wget oauth-trigger endpoint for ALL session types (text and voice), which works with every engine. Also: store userId (staffId) as the DingTalk binding ID when resolvable, falling back to openId. Bot messages deliver senderStaffId which matches userId, not openId — this prevents the "binding not found" routing failure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3ca3982c28
commit
495407d25b
|
|
@ -256,11 +256,19 @@ export class DingTalkRouterService implements OnModuleInit, OnModuleDestroy {
|
||||||
|
|
||||||
const instance = await this.instanceRepo.findById(entry.instanceId);
|
const instance = await this.instanceRepo.findById(entry.instanceId);
|
||||||
if (!instance) throw new Error('智能体实例不存在');
|
if (!instance) throw new Error('智能体实例不存在');
|
||||||
// Store openId — this matches senderId in incoming bot messages (used for routing)
|
|
||||||
instance.dingTalkUserId = openId;
|
// Store userId (staffId) as the binding identifier if resolved — this matches senderStaffId
|
||||||
|
// in incoming DingTalk bot messages, enabling correct routing.
|
||||||
|
// Fall back to openId if userId could not be resolved (routing may still work if
|
||||||
|
// DingTalk delivers openId in senderId for this app type).
|
||||||
|
const bindingId = userId ?? openId;
|
||||||
|
instance.dingTalkUserId = bindingId;
|
||||||
await this.instanceRepo.save(instance);
|
await this.instanceRepo.save(instance);
|
||||||
|
|
||||||
this.logger.log(`OAuth binding saved: instance ${entry.instanceId} → dingTalkUserId(openId)=${openId}`);
|
this.logger.log(
|
||||||
|
`OAuth binding saved: instance ${entry.instanceId} → dingTalkUserId=${bindingId} ` +
|
||||||
|
`(${userId ? 'staffId/userId' : 'openId fallback — staffId not resolved'})`,
|
||||||
|
);
|
||||||
|
|
||||||
// Send proactive greeting using userId (staffId). Skip if not resolved.
|
// Send proactive greeting using userId (staffId). Skip if not resolved.
|
||||||
this.sendGreeting(userId, openId, instance.name).catch((e: Error) =>
|
this.sendGreeting(userId, openId, instance.name).catch((e: Error) =>
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,10 @@ export class AgentController {
|
||||||
tenantId,
|
tenantId,
|
||||||
userId,
|
userId,
|
||||||
userEmail,
|
userEmail,
|
||||||
|
// Pass session ID so Claude uses the wget oauth-trigger endpoint (works for ALL engine types).
|
||||||
|
// The oauth-trigger endpoint emits an oauth_prompt WS event to this session's stream,
|
||||||
|
// which Flutter's chat page handles the same way as voice sessions.
|
||||||
|
sessionId: session.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fire-and-forget: run the task stream
|
// Fire-and-forget: run the task stream
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue