Skip to content

Commit 64b7a86

Browse files
committed
add cast safety notes and changeset for context lifecycle
1 parent 065905c commit 64b7a86

2 files changed

Lines changed: 22 additions & 3 deletions

File tree

.changeset/green-jars-turn.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"agents": minor
3+
"@cloudflare/ai-chat": patch
4+
---
5+
6+
Add hook-style runtime context lifecycle support in `agents` with `onCreateContext` / `onDestroyContext`, typed `this.context`, and context propagation via `getCurrentAgent().context` and `getCurrentContext()`.
7+
8+
Also update `@cloudflare/ai-chat` to keep `context` in the async agent scope during chat/tool execution so nested `getCurrentAgent()` reads stay consistent.

packages/agents/src/index.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -616,12 +616,19 @@ function getEmptyCurrentAgent<
616616
}
617617

618618
export function getCurrentContext(): CurrentExternalAgentContext | undefined {
619+
// Safe cast: getCurrentAgent().context is tied to
620+
// `Awaited<ReturnType<T["onCreateContext"]>>`, while this helper intentionally
621+
// exposes the external module-augmentation surface
622+
// (`CurrentExternalAgentContext`, defaulting to unknown).
619623
return getCurrentAgent().context as CurrentExternalAgentContext | undefined;
620624
}
621625

622626
export function getCurrentAgent<
623627
T extends Agent<Cloudflare.Env> = Agent<Cloudflare.Env>
624628
>(): CurrentAgentSnapshot<T> {
629+
// Safe cast: this AsyncLocalStorage is only populated by this module's
630+
// agentContext.run() call sites, all of which write the same field shape used
631+
// by CurrentAgentSnapshot. `T` only refines compile-time context typing.
625632
const store = agentContext.getStore() as CurrentAgentSnapshot<T> | undefined;
626633
return store ?? getEmptyCurrentAgent<T>();
627634
}
@@ -991,9 +998,13 @@ export class Agent<
991998
private async _resolveContext(
992999
input: AgentContextInput
9931000
): Promise<Awaited<ReturnType<this["onCreateContext"]>>> {
994-
return (await this.onCreateContext(input)) as Awaited<
995-
ReturnType<this["onCreateContext"]>
996-
>;
1001+
const contextResult = await this.onCreateContext(input);
1002+
1003+
// Safe cast: `contextResult` is the awaited runtime value from this
1004+
// instance's `onCreateContext`. The target type is exactly
1005+
// `Awaited<ReturnType<this["onCreateContext"]>>`; this cast bridges a TS
1006+
// limitation with polymorphic `this` + `ReturnType`/`Awaited` inference.
1007+
return contextResult as Awaited<ReturnType<this["onCreateContext"]>>;
9971008
}
9981009

9991010
/**

0 commit comments

Comments
 (0)