@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.
Files changed (88) hide show
  1. package/dist/chat/anthropic-planner.d.ts +8 -0
  2. package/dist/chat/anthropic-planner.js +166 -12
  3. package/dist/chat/chat-pipeline-translation.d.ts +13 -0
  4. package/dist/chat/chat-pipeline-translation.js +109 -45
  5. package/dist/chat/chat-pipeline.d.ts +1 -1
  6. package/dist/chat/chat-pipeline.js +312 -54
  7. package/dist/chat/gemini-planner.d.ts +2 -0
  8. package/dist/chat/gemini-planner.js +2 -1
  9. package/dist/chat/planner-types.d.ts +15 -0
  10. package/dist/chat/planner-types.js +2 -2
  11. package/dist/chat/planner.d.ts +12 -0
  12. package/dist/chat/planner.js +16 -2
  13. package/dist/chat/prompts.d.ts +5 -0
  14. package/dist/chat/prompts.js +92 -9
  15. package/dist/chat/translation-chunking.d.ts +124 -0
  16. package/dist/chat/translation-chunking.js +371 -0
  17. package/dist/checks/field-walk.d.ts +42 -0
  18. package/dist/checks/field-walk.js +198 -0
  19. package/dist/checks/index.d.ts +5 -0
  20. package/dist/checks/index.js +4 -0
  21. package/dist/checks/page-weight.d.ts +22 -0
  22. package/dist/checks/page-weight.js +200 -0
  23. package/dist/checks/rules-draft.d.ts +2 -0
  24. package/dist/checks/rules-draft.js +439 -0
  25. package/dist/checks/run-checks.d.ts +42 -0
  26. package/dist/checks/run-checks.js +159 -0
  27. package/dist/checks/session-runner.d.ts +19 -0
  28. package/dist/checks/session-runner.js +99 -0
  29. package/dist/checks/types.d.ts +109 -0
  30. package/dist/checks/types.js +1 -0
  31. package/dist/cms/adapter.d.ts +74 -1
  32. package/dist/cms/adapter.js +1 -0
  33. package/dist/cms/index.d.ts +1 -1
  34. package/dist/cms/index.js +1 -1
  35. package/dist/cms/media-sources.d.ts +29 -1
  36. package/dist/cms/media-sources.js +188 -7
  37. package/dist/durable/durable-store-singleton.d.ts +37 -0
  38. package/dist/durable/durable-store-singleton.js +179 -0
  39. package/dist/durable/finding-impact.d.ts +30 -0
  40. package/dist/durable/finding-impact.js +53 -0
  41. package/dist/durable/in-memory-durable-store.d.ts +203 -0
  42. package/dist/durable/in-memory-durable-store.js +363 -0
  43. package/dist/durable/index.d.ts +5 -0
  44. package/dist/durable/index.js +4 -0
  45. package/dist/durable/pending-plan-store.d.ts +28 -0
  46. package/dist/durable/pending-plan-store.js +156 -0
  47. package/dist/durable/sqlite-durable-store.d.ts +71 -0
  48. package/dist/durable/sqlite-durable-store.js +631 -0
  49. package/dist/durable/types.d.ts +265 -0
  50. package/dist/durable/types.js +1 -0
  51. package/dist/handler/create-orchestrator.d.ts +4 -0
  52. package/dist/handler/create-orchestrator.js +283 -32
  53. package/dist/http/audio-actions.d.ts +1 -1
  54. package/dist/http/checks-actions.d.ts +39 -0
  55. package/dist/http/checks-actions.js +122 -0
  56. package/dist/http/history-actions.d.ts +44 -1
  57. package/dist/http/history-actions.js +122 -0
  58. package/dist/http/image-generate-actions.d.ts +2 -2
  59. package/dist/http/ops-actions.d.ts +2 -2
  60. package/dist/http/publish-actions.d.ts +15 -4
  61. package/dist/http/publish-actions.js +3 -3
  62. package/dist/http/restore-actions.d.ts +3 -3
  63. package/dist/http/screenshot-actions.d.ts +2 -2
  64. package/dist/http/session-actions.d.ts +1 -1
  65. package/dist/http/telemetry-feedback-actions.d.ts +2 -2
  66. package/dist/http/unsplash-actions.d.ts +2 -2
  67. package/dist/http/variations-actions.d.ts +2 -2
  68. package/dist/index.d.ts +9 -2
  69. package/dist/index.js +28 -1
  70. package/dist/nlp/deterministic-planner-context.d.ts +16 -0
  71. package/dist/nlp/deterministic-planner-context.js +33 -7
  72. package/dist/nlp/intent-detection.d.ts +16 -0
  73. package/dist/nlp/intent-detection.js +15 -1
  74. package/dist/nlp/plan-normalizer.js +66 -32
  75. package/dist/ops/destructive-action-gate.js +7 -2
  76. package/dist/ops/ops-engine.d.ts +12 -1
  77. package/dist/ops/ops-engine.js +41 -14
  78. package/dist/publish/publish-helpers.d.ts +12 -2
  79. package/dist/publish/publish-helpers.js +10 -3
  80. package/dist/publish/publish-selection.d.ts +84 -0
  81. package/dist/publish/publish-selection.js +113 -0
  82. package/dist/publish/publish-target-registry.js +1 -1
  83. package/dist/publish/publish-target.d.ts +1 -1
  84. package/dist/publish/targets/git.js +2 -2
  85. package/dist/state/session-state.js +8 -1
  86. package/dist/state/site-assets.d.ts +41 -0
  87. package/dist/state/site-assets.js +40 -0
  88. 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
  /**