test: cover paths previously exercised only by invariant companions
Delete the now-unused llm-retry history helper, drop the unreachable credentials-local refresh rejection handler, and add direct tests for the gateway SRC skip of unprovided Services and llm-retry projection dedupe.
This commit is contained in:
1 parent
f028f25667
commit
963715344b
7 files changed
+45
-45
No files matched your search
@@ -454,6 +454,23 @@ describe('TypertGatewayService', () => {
|
||||
expect(service.lastSignal).toBe(abort.signal)
|
||||
})
|
||||
|
||||
it('skips declared Services without an active provider during SRC resolution', async () => {
|
||||
const { ctx } = await setup()
|
||||
const unbound = ctx.plugin(class UnboundService extends Service {
|
||||
constructor(ctx: Context) { super(ctx, 'unboundFixture') }
|
||||
})
|
||||
await unbound
|
||||
await unbound.dispose()
|
||||
registerAgentLookup(ctx, { id: 'agent-1' })
|
||||
|
||||
await expect(ctx.extend({ fixtureScope: 'unbound' }).typertGateway.invoke({
|
||||
namespace: 'goals',
|
||||
method: 'create',
|
||||
args: { agentId: 'agent-1', request: { title: 'ship' } },
|
||||
signal: new AbortController().signal,
|
||||
})).resolves.toEqual({ agentId: 'agent-1', title: 'ship', scope: 'unbound' })
|
||||
})
|
||||
|
||||
it('does not downgrade an observed SRC lookup after its provider unloads', async () => {
|
||||
const { ctx, service } = await setup()
|
||||
const dispose = registerAgentLookup(ctx, { id: 'agent-1' })
|
||||
|
||||
@@ -724,15 +724,9 @@ export class LocalCredentialProvider extends CredentialProvider {
|
||||
return task
|
||||
}
|
||||
|
||||
/** Queue a reload; only an invariant violation escaping the fan-out can reject it. */
|
||||
/** Queue a reload; `refresh()` contains its own failures, so the queued task never rejects. */
|
||||
private queueRefresh(): void {
|
||||
void this.enqueue(() => this.refresh()).catch((error: unknown) => {
|
||||
// Only an invariant violation escaping the update fan-out can reject a
|
||||
// refresh; keep the operation queue alive and surface it as an error so
|
||||
// one poisoned commit cannot silently end hot reloading forever.
|
||||
this.ctx.logger.error('credentials-local: reload commit failed at %s', this.spec.filename)
|
||||
this.ctx.logger.error(error)
|
||||
})
|
||||
void this.enqueue(() => this.refresh())
|
||||
}
|
||||
|
||||
/** Queue one line edit; entry checks reject early, the queue re-judges them at run time. */
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
en: fc4f15a14435698c
|
||||
zh: 3c6d83f5ba04ec0e
|
||||
/deepseek-ai-dsh-llm-retry/understand-the-implementation/source-map:
|
||||
en: f34b551859b68c88
|
||||
zh: 813ffa32497b1d9a
|
||||
en: 9b79cdd6597930e0
|
||||
zh: 0838f3efbc1e83ac
|
||||
/deepseek-ai-dsh-llm-retry/understand-the-implementation/recovery-flow:
|
||||
en: 85bace285b029101
|
||||
zh: 6e0237450ca6ccc0
|
||||
|
||||
@@ -76,7 +76,6 @@ The executor is built on one rule: **durable before wait, open-step boundaries.*
|
||||
| File | Role |
|
||||
|---|---|
|
||||
| [`src/index.ts`](src/index.ts) | The function plugin: waterfall listener, policy lookup, backoff, durable event appends |
|
||||
| [`src/history.ts`](src/history.ts) | Durable retry-history lookup from the session log |
|
||||
| [`src/types.ts`](src/types.ts) | Browser-safe `llm/retry` and `llm/retry-started` event payload types |
|
||||
| [`src/brand.ts`](src/brand.ts) | The `RetryId` brand shared by the event payloads |
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ kind: "package-reference"
|
||||
| 文件 | 职责 |
|
||||
|---|---|
|
||||
| [`src/index.ts`](src/index.ts) | 函数插件:waterfall 监听器、策略查找、退避、持久事件追加 |
|
||||
| [`src/history.ts`](src/history.ts) | 从会话日志查找持久重试历史 |
|
||||
| [`src/types.ts`](src/types.ts) | 浏览器安全的 `llm/retry` 与 `llm/retry-started` 事件载荷类型 |
|
||||
| [`src/brand.ts`](src/brand.ts) | 事件载荷共享的 `RetryId` 品牌 |
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/** Durable request-route lookup for one open model step. @module @deepseek-ai/dsh-llm-retry/history */
|
||||
|
||||
import type { SessionEvent } from '@deepseek-ai/dsh-session'
|
||||
|
||||
/**
|
||||
* Find the provider in force for one currently open step.
|
||||
* Request headers remain effective across turn boundaries until a newer full
|
||||
* snapshot changes them; every provider change requires a newer full snapshot.
|
||||
* @param events - session events ending inside the open step.
|
||||
* @param turn - turn that owns the failed step.
|
||||
* @param step - failed step whose provider is required.
|
||||
* @returns the provider from the request header in force for the step.
|
||||
*/
|
||||
export function providerForOpenStep(
|
||||
events: readonly SessionEvent[],
|
||||
turn: number,
|
||||
step: number,
|
||||
): string | undefined {
|
||||
const stepStartIndex = events.findLastIndex(event =>
|
||||
event.type === 'step/start'
|
||||
&& event.data.turn === turn
|
||||
&& event.data.step === step,
|
||||
)
|
||||
if (stepStartIndex < 0 || events.slice(stepStartIndex + 1).some(event =>
|
||||
event.type === 'step/end' || event.type === 'turn/end')) return undefined
|
||||
for (let index = events.length - 1; index >= 0; index -= 1) {
|
||||
// The loop bounds prove this indexed read exists.
|
||||
// oxlint-disable-next-line typescript/no-non-null-assertion
|
||||
const event = events[index]!
|
||||
if (event.type === 'request/header') return event.data.header.config.provider
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
@@ -174,6 +174,30 @@ afterEach(async () => {
|
||||
context = undefined
|
||||
})
|
||||
|
||||
describe('retry projection', () => {
|
||||
it('keeps the same state when a recorded retry is applied again', async () => {
|
||||
type Definition = { key: string; apply(state: object, event: SessionEvent): object }
|
||||
const definitions: Definition[] = []
|
||||
const { ctx } = await harness(new ScriptedAdapter([]), undefined, (inner) => {
|
||||
const projections = inner.sessionProjections
|
||||
const register = projections.register.bind(projections)
|
||||
projections.register = (spec: Definition) => {
|
||||
definitions.push(spec)
|
||||
return register(spec as never)
|
||||
}
|
||||
})
|
||||
const definition = definitions.find(spec => spec.key === 'llmRetry')!
|
||||
const event: SessionEvent = {
|
||||
type: 'llm/retry',
|
||||
data: { provider: 'mock', policyKey: 'policy', retry: 1, retryId: 'retry-1' },
|
||||
} as never
|
||||
const state = definition.apply({}, event)
|
||||
|
||||
expect(definition.apply(state, event)).toBe(state)
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
})
|
||||
|
||||
describe('provider-routed retry policy', () => {
|
||||
it('records the scheduled delay before retrying the request', async () => {
|
||||
vi.useFakeTimers()
|
||||
|
||||
Reference in new issue
Block a user