MCPcopy
hub / github.com/CopilotKit/CopilotKit / onTurn

Function onTurn

packages/bot/src/create-bot.ts:375–450  ·  view source on GitHub ↗
(turn: IncomingTurn)

Source from the content-addressed store, hash-verified

373 function makeSink(adapter: PlatformAdapter): IngressSink {
374 return {
375 async onTurn(turn: IncomingTurn) {
376 const lockKey = `turn:${turn.conversationKey}`;
377 const acquired = await backend.lock.acquire(lockKey, {
378 ttlMs: cfg.lockTtl ?? 60_000,
379 });
380
381 if (!acquired) {
382 const decision =
383 typeof cfg.onLockConflict === "function"
384 ? await cfg.onLockConflict(
385 turn.conversationKey,
386 msgFromTurn(turn),
387 )
388 : (cfg.onLockConflict ?? "drop");
389 if (decision === "drop") return; // discard overlapping turn
390 // "force": proceed WITHOUT a lock token. Does NOT cancel the
391 // in-flight handler — cooperative cancellation is a future extension.
392 }
393
394 try {
395 // Dedup AFTER acquiring the lock: a turn dropped on lock-conflict must NOT burn its
396 // eventId, so Slack's retry can still be processed once the lock frees. (A handler
397 // that throws still leaves its event marked seen — dedup drops duplicate DELIVERIES,
398 // it is not retry-of-failed-turns.)
399 if (turn.eventId) {
400 const dupKey = `evt:${adapter.platform}:${turn.eventId}`;
401 try {
402 if (await backend.dedup.seen(dupKey, cfg.dedupTtl ?? 300_000))
403 return;
404 } catch (err) {
405 console.warn(
406 `[bot] dedup check failed for ${adapter.platform}; processing without dedup`,
407 err,
408 );
409 }
410 }
411
412 // Resolve cross-platform identity key (if configured) and stamp it on
413 // the message so handlers and transcript storage can use it. Done
414 // BEFORE makeThread so the thread carries the userKey + message for
415 // the transcript auto-bridge (runAgent({ transcript: true })).
416 let userKey: string | undefined;
417 if (cfg.identity) {
418 try {
419 const resolved = await cfg.identity({
420 adapter: adapter.platform,
421 author: turn.user ?? { id: "" },
422 message: msgFromTurn(turn),
423 });
424 userKey = resolved ?? undefined;
425 } catch (err) {
426 console.warn(
427 `[bot] identity resolution failed for ${adapter.platform}; continuing without userKey`,
428 err,
429 );
430 }
431 }
432 const message: IncomingMessage = { ...msgFromTurn(turn), userKey };

Callers 2

attachSlackListenerFunction · 0.85
attachDiscordListenerFunction · 0.85

Calls 6

msgFromTurnFunction · 0.85
hFunction · 0.85
makeThreadFunction · 0.70
warnMethod · 0.65
acquireMethod · 0.45
releaseMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…