mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
refactor(ai): keep one name for one completion's ceiling
A status run is one completion, so its ceiling was the completion ceiling under a second name. The Local client also re-exported a JSON-mode helper nobody imported from it.
This commit is contained in:
1 parent
8fee138256
commit
240a135b88
7 files changed
+14
-22
No files matched your search
@@ -55,7 +55,6 @@ import { QUEUE_RUNTIME, type QueueRuntime } from "@/lib/jobs/queue-runtime";
|
||||
import {
|
||||
COMPLETION_CEILING_MS,
|
||||
COMPREHENSIVE_WARM_CEILING_MS,
|
||||
STATUS_RUN_CEILING_MS,
|
||||
} from "@/lib/jobs/model-time";
|
||||
import {
|
||||
COMPREHENSIVE_MODEL_CALLS,
|
||||
@@ -147,7 +146,7 @@ function modelSecondsOf(runs: {
|
||||
completions?: number;
|
||||
}) {
|
||||
return (
|
||||
((runs.status ?? 0) * STATUS_RUN_CEILING_MS +
|
||||
((runs.status ?? 0) * COMPLETION_CEILING_MS +
|
||||
(runs.comprehensive ?? 0) * COMPREHENSIVE_WARM_CEILING_MS +
|
||||
(runs.completions ?? 0) * COMPLETION_CEILING_MS) /
|
||||
1000
|
||||
@@ -204,7 +203,7 @@ describe("jobs that wait on the response timeout outlast it", () => {
|
||||
});
|
||||
|
||||
it("sizes the run ceilings from the largest setting and the call counts", () => {
|
||||
expect(STATUS_RUN_CEILING_MS).toBe(
|
||||
expect(COMPLETION_CEILING_MS).toBe(
|
||||
AI_RESPONSE_TIMEOUT_MAX_SECONDS * 1000 * STATUS_MODEL_CALLS,
|
||||
);
|
||||
expect(COMPREHENSIVE_WARM_CEILING_MS).toBeGreaterThan(
|
||||
@@ -238,14 +237,14 @@ describe("jobs that wait on the response timeout outlast it", () => {
|
||||
},
|
||||
"coach-memory-refresh": {
|
||||
runtime: "bounded",
|
||||
modelSeconds: STATUS_RUN_CEILING_MS / 1000,
|
||||
modelSeconds: COMPLETION_CEILING_MS / 1000,
|
||||
expireInSeconds: 1400,
|
||||
expiryVia: [],
|
||||
why: "planted: one run counted instead of three",
|
||||
},
|
||||
};
|
||||
expect(findings(before)).toEqual([
|
||||
`coach-memory-refresh: model time ${STATUS_RUN_CEILING_MS / 1000}s below the ${modelSecondsOf({ status: 3 })}s its runs take`,
|
||||
`coach-memory-refresh: model time ${COMPLETION_CEILING_MS / 1000}s below the ${modelSecondsOf({ status: 3 })}s its runs take`,
|
||||
"morning-digest-refresh: declared short, but it waits on the person's response timeout",
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import { getGlobalBoss } from "@/lib/jobs/boss-instance";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import {
|
||||
STATUS_RUN_CEILING_MS,
|
||||
COMPLETION_CEILING_MS,
|
||||
expireAboveModelTime,
|
||||
} from "@/lib/jobs/model-time";
|
||||
|
||||
@@ -41,7 +41,7 @@ export const COACH_MEMORY_MODEL_RUNS = 3;
|
||||
* beside the refresh still writing (#1274).
|
||||
*/
|
||||
export const COACH_MEMORY_REFRESH_EXPIRE_SECONDS = expireAboveModelTime(
|
||||
COACH_MEMORY_MODEL_RUNS * STATUS_RUN_CEILING_MS,
|
||||
COACH_MEMORY_MODEL_RUNS * COMPLETION_CEILING_MS,
|
||||
);
|
||||
|
||||
/** How long a conversation must be quiet before its memory is refreshed. */
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
} from "./openai-wire";
|
||||
import {
|
||||
hasLearnedJsonModeDialect,
|
||||
isResponseFormatRejection,
|
||||
jsonModeDialectFor,
|
||||
rememberJsonModeDialect,
|
||||
resetJsonModeDialectCache,
|
||||
@@ -66,8 +65,6 @@ type LocalJsonDialect = JsonModeDialect;
|
||||
/** Test hook — clears the learned per-endpoint dialect cache. */
|
||||
export const resetLocalJsonDialectCache = resetJsonModeDialectCache;
|
||||
|
||||
export { isResponseFormatRejection };
|
||||
|
||||
/**
|
||||
* #89 — the streaming path's absolute backstop. The real ceiling is the
|
||||
* per-idle-gap timer; this only stops a server that streams forever.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* worker registry and every sender can read them without loading it.
|
||||
*/
|
||||
import {
|
||||
STATUS_RUN_CEILING_MS,
|
||||
COMPLETION_CEILING_MS,
|
||||
expireAboveModelTime,
|
||||
} from "@/lib/jobs/model-time";
|
||||
|
||||
@@ -17,7 +17,7 @@ export const INSIGHT_STATUS_GENERATE_QUEUE = "insight-status-generate";
|
||||
* retry beside the generation still running (#1274).
|
||||
*/
|
||||
export const INSIGHT_STATUS_GENERATE_EXPIRE_SECONDS = expireAboveModelTime(
|
||||
STATUS_RUN_CEILING_MS,
|
||||
COMPLETION_CEILING_MS,
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -63,14 +63,11 @@ export function comprehensiveWarmBudgetMs(
|
||||
* it: the call and the one repeat the Local and gateway clients send when a
|
||||
* thinking model answered with reasoning alone (`STATUS_MODEL_CALLS`), each
|
||||
* at the full timeout. A document read's call and its corrective retry are
|
||||
* two completions.
|
||||
* two completions; a status run (`runStatusCompletion`) is one.
|
||||
*/
|
||||
export const COMPLETION_CEILING_MS =
|
||||
AI_RESPONSE_TIMEOUT_MAX_MS * STATUS_MODEL_CALLS;
|
||||
|
||||
/** The longest one status run (`runStatusCompletion`, one completion) waits. */
|
||||
export const STATUS_RUN_CEILING_MS = COMPLETION_CEILING_MS;
|
||||
|
||||
/**
|
||||
* Room a job's expiry leaves on top of its model work for what the handler
|
||||
* does around it: reading the record, building the prompt, persisting.
|
||||
|
||||
@@ -61,7 +61,6 @@ import {
|
||||
import {
|
||||
COMPLETION_CEILING_MS,
|
||||
COMPREHENSIVE_WARM_CEILING_MS,
|
||||
STATUS_RUN_CEILING_MS,
|
||||
} from "@/lib/jobs/model-time";
|
||||
import { DOCUMENT_INDEX_EXPIRE_SECONDS } from "@/lib/jobs/document-index-queue";
|
||||
import { DOCUMENT_SUMMARY_EXPIRE_SECONDS } from "@/lib/jobs/document-summary-queue";
|
||||
@@ -199,7 +198,7 @@ export const QUEUE_RUNTIME: Readonly<Record<string, QueueRuntime>> = {
|
||||
},
|
||||
"insight-status-generate": {
|
||||
runtime: "bounded",
|
||||
modelSeconds: STATUS_RUN_CEILING_MS / 1000,
|
||||
modelSeconds: COMPLETION_CEILING_MS / 1000,
|
||||
expireInSeconds: INSIGHT_STATUS_GENERATE_EXPIRE_SECONDS,
|
||||
expiryVia: ["INSIGHT_STATUS_GENERATE_EXPIRE_SECONDS"],
|
||||
why: "One account, one note: one status run, the call and its one reasoning repeat at the account's timeout.",
|
||||
@@ -208,7 +207,7 @@ export const QUEUE_RUNTIME: Readonly<Record<string, QueueRuntime>> = {
|
||||
"reaction-line-generate": short("One provider call for one reaction line."),
|
||||
"workout-insight-generate": {
|
||||
runtime: "bounded",
|
||||
modelSeconds: STATUS_RUN_CEILING_MS / 1000,
|
||||
modelSeconds: COMPLETION_CEILING_MS / 1000,
|
||||
expireInSeconds: WORKOUT_INSIGHT_GENERATE_EXPIRE_SECONDS,
|
||||
expiryVia: ["WORKOUT_INSIGHT_GENERATE_EXPIRE_SECONDS"],
|
||||
why: "One workout's line: one status run at the account's timeout.",
|
||||
@@ -235,7 +234,7 @@ export const QUEUE_RUNTIME: Readonly<Record<string, QueueRuntime>> = {
|
||||
},
|
||||
"coach-memory-refresh": {
|
||||
runtime: "bounded",
|
||||
modelSeconds: (COACH_MEMORY_MODEL_RUNS * STATUS_RUN_CEILING_MS) / 1000,
|
||||
modelSeconds: (COACH_MEMORY_MODEL_RUNS * COMPLETION_CEILING_MS) / 1000,
|
||||
expireInSeconds: COACH_MEMORY_REFRESH_EXPIRE_SECONDS,
|
||||
expiryVia: ["COACH_MEMORY_REFRESH_EXPIRE_SECONDS"],
|
||||
why: "One conversation's summary, facts and plan proposals: three status runs in a row at the account's timeout.",
|
||||
|
||||
@@ -16,7 +16,7 @@ import { getGlobalBoss } from "@/lib/jobs/boss-instance";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import { logCaught } from "@/lib/logging/signal";
|
||||
import {
|
||||
STATUS_RUN_CEILING_MS,
|
||||
COMPLETION_CEILING_MS,
|
||||
expireAboveModelTime,
|
||||
} from "@/lib/jobs/model-time";
|
||||
|
||||
@@ -30,7 +30,7 @@ export const WORKOUT_INSIGHT_GENERATE_QUEUE = "workout-insight-generate";
|
||||
* the attempt was recorded as a failure.
|
||||
*/
|
||||
export const WORKOUT_INSIGHT_GENERATE_EXPIRE_SECONDS = expireAboveModelTime(
|
||||
STATUS_RUN_CEILING_MS,
|
||||
COMPLETION_CEILING_MS,
|
||||
);
|
||||
|
||||
/** Serial — this is a provider path, kept off the request pool entirely. */
|
||||
|
||||
Reference in new issue
Block a user