@avocadostudio-ai/orchestrator-core 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat/anthropic-planner.d.ts +8 -0
- package/dist/chat/anthropic-planner.js +166 -12
- package/dist/chat/chat-pipeline-translation.d.ts +13 -0
- package/dist/chat/chat-pipeline-translation.js +109 -45
- package/dist/chat/chat-pipeline.d.ts +1 -1
- package/dist/chat/chat-pipeline.js +312 -54
- package/dist/chat/gemini-planner.d.ts +2 -0
- package/dist/chat/gemini-planner.js +2 -1
- package/dist/chat/planner-types.d.ts +15 -0
- package/dist/chat/planner-types.js +2 -2
- package/dist/chat/planner.d.ts +12 -0
- package/dist/chat/planner.js +16 -2
- package/dist/chat/prompts.d.ts +5 -0
- package/dist/chat/prompts.js +92 -9
- package/dist/chat/translation-chunking.d.ts +124 -0
- package/dist/chat/translation-chunking.js +371 -0
- package/dist/checks/field-walk.d.ts +42 -0
- package/dist/checks/field-walk.js +198 -0
- package/dist/checks/index.d.ts +5 -0
- package/dist/checks/index.js +4 -0
- package/dist/checks/page-weight.d.ts +22 -0
- package/dist/checks/page-weight.js +200 -0
- package/dist/checks/rules-draft.d.ts +2 -0
- package/dist/checks/rules-draft.js +439 -0
- package/dist/checks/run-checks.d.ts +42 -0
- package/dist/checks/run-checks.js +159 -0
- package/dist/checks/session-runner.d.ts +19 -0
- package/dist/checks/session-runner.js +99 -0
- package/dist/checks/types.d.ts +109 -0
- package/dist/checks/types.js +1 -0
- package/dist/cms/adapter.d.ts +74 -1
- package/dist/cms/adapter.js +1 -0
- package/dist/cms/index.d.ts +1 -1
- package/dist/cms/index.js +1 -1
- package/dist/cms/media-sources.d.ts +29 -1
- package/dist/cms/media-sources.js +188 -7
- package/dist/durable/durable-store-singleton.d.ts +37 -0
- package/dist/durable/durable-store-singleton.js +179 -0
- package/dist/durable/finding-impact.d.ts +30 -0
- package/dist/durable/finding-impact.js +53 -0
- package/dist/durable/in-memory-durable-store.d.ts +203 -0
- package/dist/durable/in-memory-durable-store.js +363 -0
- package/dist/durable/index.d.ts +5 -0
- package/dist/durable/index.js +4 -0
- package/dist/durable/pending-plan-store.d.ts +28 -0
- package/dist/durable/pending-plan-store.js +156 -0
- package/dist/durable/sqlite-durable-store.d.ts +71 -0
- package/dist/durable/sqlite-durable-store.js +631 -0
- package/dist/durable/types.d.ts +265 -0
- package/dist/durable/types.js +1 -0
- package/dist/handler/create-orchestrator.d.ts +4 -0
- package/dist/handler/create-orchestrator.js +283 -32
- package/dist/http/audio-actions.d.ts +1 -1
- package/dist/http/checks-actions.d.ts +39 -0
- package/dist/http/checks-actions.js +122 -0
- package/dist/http/history-actions.d.ts +44 -1
- package/dist/http/history-actions.js +122 -0
- package/dist/http/image-generate-actions.d.ts +2 -2
- package/dist/http/ops-actions.d.ts +2 -2
- package/dist/http/publish-actions.d.ts +15 -4
- package/dist/http/publish-actions.js +3 -3
- package/dist/http/restore-actions.d.ts +3 -3
- package/dist/http/screenshot-actions.d.ts +2 -2
- package/dist/http/session-actions.d.ts +1 -1
- package/dist/http/telemetry-feedback-actions.d.ts +2 -2
- package/dist/http/unsplash-actions.d.ts +2 -2
- package/dist/http/variations-actions.d.ts +2 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +28 -1
- package/dist/nlp/deterministic-planner-context.d.ts +16 -0
- package/dist/nlp/deterministic-planner-context.js +33 -7
- package/dist/nlp/intent-detection.d.ts +16 -0
- package/dist/nlp/intent-detection.js +15 -1
- package/dist/nlp/plan-normalizer.js +66 -32
- package/dist/ops/destructive-action-gate.js +7 -2
- package/dist/ops/ops-engine.d.ts +12 -1
- package/dist/ops/ops-engine.js +41 -14
- package/dist/publish/publish-helpers.d.ts +12 -2
- package/dist/publish/publish-helpers.js +10 -3
- package/dist/publish/publish-selection.d.ts +84 -0
- package/dist/publish/publish-selection.js +113 -0
- package/dist/publish/publish-target-registry.js +1 -1
- package/dist/publish/publish-target.d.ts +1 -1
- package/dist/publish/targets/git.js +2 -2
- package/dist/state/session-state.js +8 -1
- package/dist/state/site-assets.d.ts +41 -0
- package/dist/state/site-assets.js +40 -0
- package/package.json +3 -3
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import type { Operation } from "@avocadostudio-ai/shared";
|
|
2
|
+
export type FindingSeverity = "error" | "warning" | "info";
|
|
3
|
+
/**
|
|
4
|
+
* `open` → a live problem. `fixed` is set by reconciliation, never by a rule.
|
|
5
|
+
* `dismissed` and `snoozed` are the user's decision and must survive every
|
|
6
|
+
* subsequent run — a checker whose dismissals evaporate is a checker people
|
|
7
|
+
* turn off in week two.
|
|
8
|
+
*
|
|
9
|
+
* The two are not synonyms, and the difference is a clock: `dismissed` means
|
|
10
|
+
* *never show me this again*, `snoozed` means *not this week*. A snooze without
|
|
11
|
+
* an expiry is a second word for dismiss, so a snoozed record carries
|
|
12
|
+
* `snoozedUntil` and `wakeSnoozedFindings` reopens it when that passes.
|
|
13
|
+
*/
|
|
14
|
+
export type FindingStatus = "open" | "snoozed" | "dismissed" | "fixed";
|
|
15
|
+
export type FindingEvidence = {
|
|
16
|
+
source: "draft" | "rendered" | "model";
|
|
17
|
+
blockId?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Carried so a client can select the block without a lookup. The editor's
|
|
20
|
+
* property panel collapses to its page-level fallback when it is handed an
|
|
21
|
+
* id with no type, so a finding that knows the block but not its type sends
|
|
22
|
+
* the user to a panel that cannot show them the field.
|
|
23
|
+
*/
|
|
24
|
+
blockType?: string;
|
|
25
|
+
/**
|
|
26
|
+
* The block's own heading, for telling two blocks of one type apart. A page
|
|
27
|
+
* with three Card Grids yields three findings that all read
|
|
28
|
+
* `cards[0].imageAlt`; without this the panel cannot say which is which and
|
|
29
|
+
* the reader has to press "Go to" on each to find out.
|
|
30
|
+
*/
|
|
31
|
+
blockLabel?: string;
|
|
32
|
+
/** Editable path into the block props, e.g. `meta.description`. */
|
|
33
|
+
path?: string;
|
|
34
|
+
excerpt?: string;
|
|
35
|
+
};
|
|
36
|
+
export type FindingInput = {
|
|
37
|
+
/** Stable across runs. Excludes the offending *value* — see `fingerprint`. */
|
|
38
|
+
fingerprint: string;
|
|
39
|
+
scopeKey: string;
|
|
40
|
+
slug: string;
|
|
41
|
+
ruleId: string;
|
|
42
|
+
agent: string;
|
|
43
|
+
severity: FindingSeverity;
|
|
44
|
+
/**
|
|
45
|
+
* Severity × how much the page matters, 0–1. See `finding-impact.ts`.
|
|
46
|
+
*
|
|
47
|
+
* Recomputed by every run rather than fixed at first sight, because the page
|
|
48
|
+
* weight it derives from moves: link a page from the nav and its findings
|
|
49
|
+
* become more important than they were this morning, without anything about
|
|
50
|
+
* the findings themselves having changed.
|
|
51
|
+
*
|
|
52
|
+
* Optional on the way in — a caller that has not scored its pages should get
|
|
53
|
+
* the neutral fallback rather than a made-up number.
|
|
54
|
+
*/
|
|
55
|
+
impact?: number;
|
|
56
|
+
title: string;
|
|
57
|
+
detail?: string;
|
|
58
|
+
evidence?: FindingEvidence;
|
|
59
|
+
/** Ops that would resolve the finding. Applied only through the normal gate. */
|
|
60
|
+
proposedOps?: Operation[];
|
|
61
|
+
};
|
|
62
|
+
export type FindingRecord = FindingInput & {
|
|
63
|
+
id: string;
|
|
64
|
+
/** Always present on a record; `fallbackImpact` fills it for unscored rows. */
|
|
65
|
+
impact: number;
|
|
66
|
+
status: FindingStatus;
|
|
67
|
+
/** The run that most recently emitted this finding. Reconciliation reads it. */
|
|
68
|
+
lastRunId: string;
|
|
69
|
+
firstSeenAt: number;
|
|
70
|
+
lastSeenAt: number;
|
|
71
|
+
resolvedAt?: number;
|
|
72
|
+
/** When a `snoozed` record becomes `open` again. Set only for that status. */
|
|
73
|
+
snoozedUntil?: number;
|
|
74
|
+
};
|
|
75
|
+
export type FindingQuery = {
|
|
76
|
+
scopeKey: string;
|
|
77
|
+
slug?: string;
|
|
78
|
+
agent?: string;
|
|
79
|
+
status?: FindingStatus | FindingStatus[];
|
|
80
|
+
severity?: FindingSeverity;
|
|
81
|
+
limit?: number;
|
|
82
|
+
};
|
|
83
|
+
export type CheckRunTrigger = "manual" | "on_apply" | "on_publish" | "scheduled" | "webhook";
|
|
84
|
+
export type CheckRunInput = {
|
|
85
|
+
id: string;
|
|
86
|
+
scopeKey: string;
|
|
87
|
+
agent: string;
|
|
88
|
+
trigger: CheckRunTrigger;
|
|
89
|
+
startedAt: number;
|
|
90
|
+
};
|
|
91
|
+
export type CheckRunRecord = CheckRunInput & {
|
|
92
|
+
finishedAt?: number;
|
|
93
|
+
pagesScanned: number;
|
|
94
|
+
findingsOpened: number;
|
|
95
|
+
findingsClosed: number;
|
|
96
|
+
/** Model spend for the judgement tier. Cost invisible is cost unbounded. */
|
|
97
|
+
costUsd: number;
|
|
98
|
+
error?: string;
|
|
99
|
+
};
|
|
100
|
+
export type CheckRunPatch = Partial<Omit<CheckRunRecord, keyof CheckRunInput>>;
|
|
101
|
+
export type MemoryScope = "site" | "session" | "page";
|
|
102
|
+
export type MemoryKind = "fact" | "preference" | "decision" | "glossary";
|
|
103
|
+
export type MemorySource = "user" | "inferred" | "agent" | "import";
|
|
104
|
+
export type MemoryStatus = "active" | "superseded" | "rejected";
|
|
105
|
+
export type MemoryInput = {
|
|
106
|
+
scope: MemoryScope;
|
|
107
|
+
scopeKey: string;
|
|
108
|
+
kind: MemoryKind;
|
|
109
|
+
/** Namespaced, unique per (scope, scopeKey, kind). A new value supersedes. */
|
|
110
|
+
key: string;
|
|
111
|
+
value: string;
|
|
112
|
+
source: MemorySource;
|
|
113
|
+
/** traceId, findingId or run id — whatever lets a human audit the claim. */
|
|
114
|
+
sourceRef?: string;
|
|
115
|
+
/** 0–1. `inferred` should enter low; a wrong remembered fact steers silently. */
|
|
116
|
+
confidence?: number;
|
|
117
|
+
};
|
|
118
|
+
export type MemoryRecord = Required<Pick<MemoryInput, "confidence">> & MemoryInput & {
|
|
119
|
+
id: string;
|
|
120
|
+
status: MemoryStatus;
|
|
121
|
+
supersedesId?: string;
|
|
122
|
+
createdAt: number;
|
|
123
|
+
lastUsedAt?: number;
|
|
124
|
+
useCount: number;
|
|
125
|
+
};
|
|
126
|
+
export type MemoryQuery = {
|
|
127
|
+
scopeKey?: string;
|
|
128
|
+
scope?: MemoryScope;
|
|
129
|
+
kind?: MemoryKind | MemoryKind[];
|
|
130
|
+
status?: MemoryStatus;
|
|
131
|
+
limit?: number;
|
|
132
|
+
};
|
|
133
|
+
export type CorrectionOutcome = "accepted" | "edited" | "rejected" | "undone";
|
|
134
|
+
export type CorrectionInput = {
|
|
135
|
+
traceId: string;
|
|
136
|
+
scopeKey: string;
|
|
137
|
+
slug?: string;
|
|
138
|
+
request: string;
|
|
139
|
+
proposed: Operation[];
|
|
140
|
+
outcome: CorrectionOutcome;
|
|
141
|
+
/** What actually landed, when the human edited rather than accepted. */
|
|
142
|
+
applied?: Operation[];
|
|
143
|
+
};
|
|
144
|
+
export type CorrectionRecord = CorrectionInput & {
|
|
145
|
+
id: string;
|
|
146
|
+
at: number;
|
|
147
|
+
};
|
|
148
|
+
export type CorrectionQuery = {
|
|
149
|
+
scopeKey?: string;
|
|
150
|
+
outcome?: CorrectionOutcome;
|
|
151
|
+
since?: number;
|
|
152
|
+
limit?: number;
|
|
153
|
+
};
|
|
154
|
+
export type ProposalStatus = "pending" | "approved" | "discarded" | "expired";
|
|
155
|
+
/**
|
|
156
|
+
* `pendingApprovalPlanBySession` is an in-memory Map, not persisted, evicted by
|
|
157
|
+
* age. That is fine for "you typed a sentence and approved it ten seconds
|
|
158
|
+
* later" and useless for an agent that runs at 03:00: the plan it produced has
|
|
159
|
+
* nowhere to live until morning.
|
|
160
|
+
*/
|
|
161
|
+
export type ProposalInput = {
|
|
162
|
+
id: string;
|
|
163
|
+
scopeKey: string;
|
|
164
|
+
/** Which agent or chat turn produced it. */
|
|
165
|
+
origin: string;
|
|
166
|
+
summary: string;
|
|
167
|
+
ops: Operation[];
|
|
168
|
+
slugs: string[];
|
|
169
|
+
/** The finding this proposal resolves, when it came from one. */
|
|
170
|
+
findingId?: string;
|
|
171
|
+
/**
|
|
172
|
+
* Opaque to this store: whatever the producer needs to reconstruct its own
|
|
173
|
+
* richer object. The chat pipeline's `PendingApprovalPlan` carries a prompt
|
|
174
|
+
* hash, a model key, pending image ops and the destructive-gate reasons, none
|
|
175
|
+
* of which belong in a generic proposals table — and all of which have to
|
|
176
|
+
* survive a restart, or rehydration hands back a plan the approval path
|
|
177
|
+
* cannot execute.
|
|
178
|
+
*
|
|
179
|
+
* `ops`/`slugs`/`summary` stay typed so a consumer that only wants to show or
|
|
180
|
+
* apply the plan never has to know what produced it.
|
|
181
|
+
*/
|
|
182
|
+
payload?: Record<string, unknown>;
|
|
183
|
+
createdAt: number;
|
|
184
|
+
expiresAt?: number;
|
|
185
|
+
};
|
|
186
|
+
export type ProposalRecord = ProposalInput & {
|
|
187
|
+
status: ProposalStatus;
|
|
188
|
+
resolvedAt?: number;
|
|
189
|
+
};
|
|
190
|
+
export type ProposalQuery = {
|
|
191
|
+
scopeKey: string;
|
|
192
|
+
status?: ProposalStatus;
|
|
193
|
+
limit?: number;
|
|
194
|
+
};
|
|
195
|
+
export interface DurableStore {
|
|
196
|
+
/**
|
|
197
|
+
* Upsert by fingerprint. An existing record keeps its `firstSeenAt` and — the
|
|
198
|
+
* part that matters — its `status`, so a dismissal survives every re-run. A
|
|
199
|
+
* record previously reconciled to `fixed` reopens.
|
|
200
|
+
*
|
|
201
|
+
* Returns counts, not records, because the caller is a run loop that wants a
|
|
202
|
+
* ledger line and not a page of rows.
|
|
203
|
+
*/
|
|
204
|
+
recordFindings(runId: string, findings: FindingInput[]): Promise<{
|
|
205
|
+
opened: number;
|
|
206
|
+
updated: number;
|
|
207
|
+
}>;
|
|
208
|
+
/**
|
|
209
|
+
* Close every `open` or `snoozed` finding in scope that this run did not
|
|
210
|
+
* re-emit. The absence *is* the signal — nothing has to notice a problem went
|
|
211
|
+
* away.
|
|
212
|
+
*
|
|
213
|
+
* Snoozed rows are included because a snooze postpones the *report*, not the
|
|
214
|
+
* problem: leave them out and a finding somebody deferred on Monday, then
|
|
215
|
+
* fixed on Tuesday, comes back on Friday as an open finding about a page that
|
|
216
|
+
* is fine.
|
|
217
|
+
*
|
|
218
|
+
* `slugs` bounds it to what the run actually scanned: a run over two pages
|
|
219
|
+
* must not close findings on the other forty-three.
|
|
220
|
+
*/
|
|
221
|
+
reconcileFindings(args: {
|
|
222
|
+
runId: string;
|
|
223
|
+
scopeKey: string;
|
|
224
|
+
slugs: string[];
|
|
225
|
+
agent?: string;
|
|
226
|
+
at?: number;
|
|
227
|
+
}): Promise<{
|
|
228
|
+
closed: number;
|
|
229
|
+
}>;
|
|
230
|
+
listFindings(query: FindingQuery): Promise<FindingRecord[]>;
|
|
231
|
+
getFinding(id: string): Promise<FindingRecord | null>;
|
|
232
|
+
/**
|
|
233
|
+
* `snoozed` derives its own `snoozedUntil` from `at` plus `SNOOZE_WINDOW_MS`
|
|
234
|
+
* rather than taking one, so every caller and every implementation agree on
|
|
235
|
+
* what a snooze is worth. Nothing else may set it.
|
|
236
|
+
*/
|
|
237
|
+
setFindingStatus(id: string, status: FindingStatus, at?: number): Promise<void>;
|
|
238
|
+
/**
|
|
239
|
+
* Reopen snoozed findings whose window has passed. The read paths call it, so
|
|
240
|
+
* a snooze ends without anything having to be scheduled — the same shape as
|
|
241
|
+
* `expireProposals`, and for the same reason: there is no cron here.
|
|
242
|
+
*/
|
|
243
|
+
wakeSnoozedFindings(scopeKey: string, now?: number): Promise<{
|
|
244
|
+
woken: number;
|
|
245
|
+
}>;
|
|
246
|
+
startCheckRun(run: CheckRunInput): Promise<CheckRunRecord>;
|
|
247
|
+
finishCheckRun(id: string, patch: CheckRunPatch): Promise<void>;
|
|
248
|
+
listCheckRuns(scopeKey: string, limit?: number): Promise<CheckRunRecord[]>;
|
|
249
|
+
/** Supersedes the active record with the same (scope, scopeKey, kind, key). */
|
|
250
|
+
putMemory(input: MemoryInput, at?: number): Promise<MemoryRecord>;
|
|
251
|
+
listMemory(query: MemoryQuery): Promise<MemoryRecord[]>;
|
|
252
|
+
/** Bump `lastUsedAt`/`useCount` for records that were actually sent to a model. */
|
|
253
|
+
touchMemory(ids: string[], at?: number): Promise<void>;
|
|
254
|
+
setMemoryStatus(id: string, status: MemoryStatus): Promise<void>;
|
|
255
|
+
recordCorrection(input: CorrectionInput, at?: number): Promise<CorrectionRecord>;
|
|
256
|
+
listCorrections(query?: CorrectionQuery): Promise<CorrectionRecord[]>;
|
|
257
|
+
putProposal(input: ProposalInput): Promise<ProposalRecord>;
|
|
258
|
+
getProposal(id: string): Promise<ProposalRecord | null>;
|
|
259
|
+
listProposals(query: ProposalQuery): Promise<ProposalRecord[]>;
|
|
260
|
+
setProposalStatus(id: string, status: ProposalStatus, at?: number): Promise<void>;
|
|
261
|
+
/** Sweep proposals past `expiresAt`. Returns how many were expired. */
|
|
262
|
+
expireProposals(now?: number): Promise<{
|
|
263
|
+
expired: number;
|
|
264
|
+
}>;
|
|
265
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -167,6 +167,10 @@ export interface CreateOrchestratorConfig {
|
|
|
167
167
|
*
|
|
168
168
|
* Omit it if you render Avocado's blocks (a scaffolded site does). The
|
|
169
169
|
* declaration is exclusive: nothing outside the list is offered or accepted.
|
|
170
|
+
*
|
|
171
|
+
* Pass the same list to `createEditorApiHandler`. That handler serves
|
|
172
|
+
* `/api/editor/blocks`, the manifest the editor reads, and it is routinely
|
|
173
|
+
* asked for it before anything has caused this module to be evaluated.
|
|
170
174
|
*/
|
|
171
175
|
blockTypes?: readonly string[];
|
|
172
176
|
/**
|