refactor: narrow synchronous extension contracts

This commit is contained in:
Tianyi Cui
2026-07-13 11:58:55 +08:00
parent f7b9cea733
commit f32cfafa1a
33 changed files with 148 additions and 126 deletions
+12 -9
View File
@@ -434,7 +434,7 @@ export class SystemPrompt extends Service {
* Cordis effect disposer (single-shot): composite (generator) effects may
* yield it directly — exact identity nests the teardown in order.
*/
section(section: PromptSection): () => Promise<void> | void {
section(section: PromptSection): () => void {
if (!Number.isFinite(section.order)) {
throw new TypeError(`prompt section "${section.name}" order must be a finite number`)
}
@@ -481,8 +481,9 @@ export class SystemPrompt extends Service {
// effect that owns a teardown ORDER must be able to yield THIS function —
// cordis nests a disposer out of the fiber's concurrent sibling list by
// exact function identity, so a wrapper would silently break the nesting
// (the agents.register() lesson). Fire-and-forget callers may still
// discard the (always-resolved) promise.
// (the agents.register() lesson). Cleanup is synchronous because this
// registration installs only synchronous state and notifications.
// eslint-disable-next-line @typescript-eslint/no-misused-promises -- synchronous cleanup; direct return preserves disposer identity
return dispose
}
@@ -502,7 +503,7 @@ export class SystemPrompt extends Service {
* Cordis effect disposer (single-shot): composite (generator) effects may
* yield it directly — exact identity nests the teardown in order.
*/
tools(provider: (context: AssembleContext) => ToolProviderResult): () => Promise<void> | void {
tools(provider: (context: AssembleContext) => ToolProviderResult): () => void {
const scope = scopeOf(this.ctx)
const dispose = this.ctx.effect(function* (this: SystemPrompt) {
const layer = scope === undefined
@@ -527,8 +528,9 @@ export class SystemPrompt extends Service {
// effect that owns a teardown ORDER must be able to yield THIS function —
// cordis nests a disposer out of the fiber's concurrent sibling list by
// exact function identity, so a wrapper would silently break the nesting
// (the agents.register() lesson). Fire-and-forget callers may still
// discard the (always-resolved) promise.
// (the agents.register() lesson). Cleanup is synchronous because this
// registration installs only synchronous state and notifications.
// eslint-disable-next-line @typescript-eslint/no-misused-promises -- synchronous cleanup; direct return preserves disposer identity
return dispose
}
@@ -550,7 +552,7 @@ export class SystemPrompt extends Service {
* Cordis effect disposer (single-shot): composite (generator) effects may
* yield it directly — exact identity nests the teardown in order.
*/
variable(name: string, provider: (context: AssembleContext) => string | undefined): () => Promise<void> | void {
variable(name: string, provider: (context: AssembleContext) => string | undefined): () => void {
if (!VARIABLE_NAME.test(name)) {
throw new Error(`invalid prompt variable name "${name}" (must match ${String(VARIABLE_NAME)})`)
}
@@ -581,8 +583,9 @@ export class SystemPrompt extends Service {
// effect that owns a teardown ORDER must be able to yield THIS function —
// cordis nests a disposer out of the fiber's concurrent sibling list by
// exact function identity, so a wrapper would silently break the nesting
// (the agents.register() lesson). Fire-and-forget callers may still
// discard the (always-resolved) promise.
// (the agents.register() lesson). Cleanup is synchronous because this
// registration installs only synchronous state and notifications.
// eslint-disable-next-line @typescript-eslint/no-misused-promises -- synchronous cleanup; direct return preserves disposer identity
return dispose
}