@ggui-ai/mcp-server-handlers 0.25.0 → 0.26.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/README.md +2 -2
- package/dist/credits/index.d.ts +2 -2
- package/dist/credits/index.d.ts.map +1 -1
- package/dist/credits/index.js +1 -1
- package/dist/credits/list-credit-transactions.d.ts +21 -7
- package/dist/credits/list-credit-transactions.d.ts.map +1 -1
- package/dist/credits/list-credit-transactions.js +12 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/ops-blueprint/cache-mirror.d.ts +41 -0
- package/dist/ops-blueprint/cache-mirror.d.ts.map +1 -0
- package/dist/ops-blueprint/cache-mirror.js +19 -0
- package/dist/ops-blueprint/delete.d.ts +18 -0
- package/dist/ops-blueprint/delete.d.ts.map +1 -1
- package/dist/ops-blueprint/delete.js +21 -2
- package/dist/ops-blueprint/errors.d.ts +11 -0
- package/dist/ops-blueprint/errors.d.ts.map +1 -1
- package/dist/ops-blueprint/errors.js +14 -0
- package/dist/ops-blueprint/generate.d.ts +1 -3
- package/dist/ops-blueprint/generate.d.ts.map +1 -1
- package/dist/ops-blueprint/generate.js +47 -58
- package/dist/ops-blueprint/list.d.ts.map +1 -1
- package/dist/ops-blueprint/list.js +1 -2
- package/dist/ops-blueprint/register.d.ts +17 -6
- package/dist/ops-blueprint/register.d.ts.map +1 -1
- package/dist/ops-blueprint/register.js +77 -45
- package/dist/ops-blueprint/update.d.ts +3 -2
- package/dist/ops-blueprint/update.d.ts.map +1 -1
- package/dist/ops-blueprint/update.js +4 -3
- package/dist/renders/blueprint-coverage.d.ts +23 -4
- package/dist/renders/blueprint-coverage.d.ts.map +1 -1
- package/dist/renders/blueprint-coverage.js +45 -5
- package/dist/renders/blueprint-durability.d.ts.map +1 -1
- package/dist/renders/blueprint-durability.js +5 -0
- package/dist/renders/blueprint-matcher.d.ts +28 -0
- package/dist/renders/blueprint-matcher.d.ts.map +1 -1
- package/dist/renders/blueprint-matcher.js +39 -7
- package/dist/renders/blueprint-registry.d.ts +52 -1
- package/dist/renders/blueprint-registry.d.ts.map +1 -1
- package/dist/renders/blueprint-registry.js +137 -10
- package/dist/renders/build-seed-pool.d.ts.map +1 -1
- package/dist/renders/build-seed-pool.js +6 -0
- package/dist/renders/consume.d.ts +3 -2
- package/dist/renders/consume.d.ts.map +1 -1
- package/dist/renders/consume.js +23 -14
- package/dist/renders/cross-app-refused.d.ts +3 -2
- package/dist/renders/cross-app-refused.d.ts.map +1 -1
- package/dist/renders/cross-app-refused.js +5 -3
- package/dist/renders/decide-handshake.d.ts +28 -0
- package/dist/renders/decide-handshake.d.ts.map +1 -1
- package/dist/renders/decide-handshake.js +39 -4
- package/dist/renders/export-registry.d.ts +8 -1
- package/dist/renders/export-registry.d.ts.map +1 -1
- package/dist/renders/export-registry.js +3 -0
- package/dist/renders/fits.d.ts.map +1 -1
- package/dist/renders/fits.js +23 -1
- package/dist/renders/handshake.d.ts +6 -42
- package/dist/renders/handshake.d.ts.map +1 -1
- package/dist/renders/handshake.js +1 -1
- package/dist/renders/index.d.ts +5 -4
- package/dist/renders/index.d.ts.map +1 -1
- package/dist/renders/index.js +4 -3
- package/dist/renders/installed-blueprints-provider.d.ts.map +1 -1
- package/dist/renders/installed-blueprints-provider.js +3 -1
- package/dist/renders/match-precision/pairs.d.ts +5 -4
- package/dist/renders/match-precision/pairs.d.ts.map +1 -1
- package/dist/renders/match-precision/topk-probe.js +13 -8
- package/dist/renders/record-committed-one-shot.d.ts +18 -3
- package/dist/renders/record-committed-one-shot.d.ts.map +1 -1
- package/dist/renders/record-committed-one-shot.js +14 -7
- package/dist/renders/refresh-ws-token.d.ts +9 -12
- package/dist/renders/refresh-ws-token.d.ts.map +1 -1
- package/dist/renders/refresh-ws-token.js +13 -10
- package/dist/renders/render-identity.d.ts +14 -5
- package/dist/renders/render-identity.d.ts.map +1 -1
- package/dist/renders/render-identity.js +25 -12
- package/dist/renders/render-read-gate.d.ts +27 -1
- package/dist/renders/render-read-gate.d.ts.map +1 -1
- package/dist/renders/render-read-gate.js +17 -5
- package/dist/renders/render.d.ts +36 -19
- package/dist/renders/render.d.ts.map +1 -1
- package/dist/renders/render.js +174 -17
- package/dist/renders/report-render-failure.d.ts +69 -0
- package/dist/renders/report-render-failure.d.ts.map +1 -0
- package/dist/renders/report-render-failure.js +83 -0
- package/dist/renders/runtime-pull.d.ts.map +1 -1
- package/dist/renders/runtime-pull.js +6 -0
- package/dist/renders/slice-meta-derivation.d.ts +8 -1
- package/dist/renders/slice-meta-derivation.d.ts.map +1 -1
- package/dist/renders/slice-meta-derivation.js +1 -0
- package/dist/renders/submit-action.d.ts +41 -71
- package/dist/renders/submit-action.d.ts.map +1 -1
- package/dist/renders/submit-action.js +225 -78
- package/dist/renders/sync-context.d.ts +3 -1
- package/dist/renders/sync-context.d.ts.map +1 -1
- package/dist/renders/sync-context.js +38 -8
- package/dist/types.d.ts +71 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +32 -0
- package/package.json +8 -8
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Sibling of `ggui_ops_generate_blueprint`. Same persistence seams +
|
|
6
6
|
* dual-write (BlueprintStore + cache vectorStore via registerBlueprint),
|
|
7
|
-
* same variance + default
|
|
7
|
+
* same variance + operator-default mark semantics. The only difference is the
|
|
8
8
|
* code body: instead of dispatching through `generator.generate(...)`
|
|
9
9
|
* to produce componentCode, the operator supplies the bytes directly
|
|
10
10
|
* and the handler persists them verbatim.
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
* ops_generate — schema-compat + hygiene-3 lint live elsewhere.
|
|
37
37
|
*/
|
|
38
38
|
import type { AppMetadataStore, BlueprintStore, TelemetrySink } from "@ggui-ai/mcp-server-core";
|
|
39
|
-
import { type Blueprint, type DataContract, type LlmBlueprintSource, type UserBlueprintSource } from "@ggui-ai/protocol";
|
|
39
|
+
import { type Blueprint, type DataContract, type GeneratorBuild, type LlmBlueprintSource, type UserBlueprintSource } from "@ggui-ai/protocol";
|
|
40
40
|
import { z } from "zod";
|
|
41
41
|
import { type BlueprintRegistryDeps } from "../renders/index.js";
|
|
42
42
|
import { type HandlerContext } from "../types.js";
|
|
@@ -132,6 +132,7 @@ export declare function createGguiOpsRegisterBlueprintHandler(deps: GguiOpsRegis
|
|
|
132
132
|
request: "request";
|
|
133
133
|
}>>;
|
|
134
134
|
setAsOperatorDefault: z.ZodOptional<z.ZodBoolean>;
|
|
135
|
+
clonedFrom: z.ZodOptional<z.ZodString>;
|
|
135
136
|
}, {
|
|
136
137
|
blueprintId: z.ZodString;
|
|
137
138
|
codeHash: z.ZodString;
|
|
@@ -165,6 +166,14 @@ export interface GeneratedBlueprintBytes {
|
|
|
165
166
|
* claim nobody made. Validated against the protocol's schema.
|
|
166
167
|
*/
|
|
167
168
|
readonly source: LlmBlueprintSource;
|
|
169
|
+
/**
|
|
170
|
+
* ggui#1280 — the build the generation reported (`metadata.build`),
|
|
171
|
+
* verbatim. Admitted by the registry's one rule (`admitGeneratorBuild`):
|
|
172
|
+
* a stamp that fails the protocol's `generatorBuildSchema` is dropped
|
|
173
|
+
* with a `blueprint_build_stamp_dropped` line and the row registers
|
|
174
|
+
* unstamped, so a bad stamp never refuses a registration.
|
|
175
|
+
*/
|
|
176
|
+
readonly build?: GeneratorBuild;
|
|
168
177
|
}
|
|
169
178
|
/** What {@link createRegisterGeneratedBlueprint}'s entry returns. */
|
|
170
179
|
export interface RegisterGeneratedBlueprintOutput {
|
|
@@ -184,10 +193,12 @@ export type RegisterGeneratedBlueprint = (input: Record<string, unknown>, genera
|
|
|
184
193
|
* with the authored source they were compiled from, in-process.
|
|
185
194
|
*
|
|
186
195
|
* Same body as `ggui_ops_register_blueprint` (one durable row, one cache
|
|
187
|
-
* mirror, the same gates and variance), with
|
|
188
|
-
* is the generation's `llm` arm
|
|
189
|
-
*
|
|
190
|
-
* (`ggui_get_render_source`, save-to-library)
|
|
196
|
+
* mirror, the same gates and variance), with three differences: provenance
|
|
197
|
+
* is the generation's `llm` arm; the authored source reaches the cache
|
|
198
|
+
* registry, so a render that reuses the registration serves it
|
|
199
|
+
* (`ggui_get_render_source`, save-to-library); and the generation's build,
|
|
200
|
+
* when the caller passes one, is stamped on the durable rows (ggui#1280).
|
|
201
|
+
* It is NOT an MCP tool and
|
|
191
202
|
* is on no wire: the public operator door stays source-free, because it
|
|
192
203
|
* cannot verify that supplied source compiles to the supplied code.
|
|
193
204
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/register.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,SAAS,EAEd,KAAK,YAAY,EACjB,KAAK,kBAAkB,EAGvB,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/register.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,SAAS,EAEd,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EAGvB,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAuB,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEtF,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACxF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAkBjD;;;;;;;GAOG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;IAC1E;;;;;;;OAOG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAC/B;;;;;;;;OAQG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,qBAAqB,CAAC;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC;;OAEG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC;IACxC;;;;;;;OAOG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CACzD;AA0QD,wBAAgB,qCAAqC,CACnD,IAAI,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BnC;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,qEAAqE;AACrE,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;CACrC;AAED;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,GAAG,CACvC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,SAAS,EAAE,uBAAuB,EAClC,GAAG,EAAE,cAAc,KAChB,OAAO,CAAC,gCAAgC,CAAC,CAAC;AAE/C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,4BAA4B,GACjC,0BAA0B,CAkB5B"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Sibling of `ggui_ops_generate_blueprint`. Same persistence seams +
|
|
6
6
|
* dual-write (BlueprintStore + cache vectorStore via registerBlueprint),
|
|
7
|
-
* same variance + default
|
|
7
|
+
* same variance + operator-default mark semantics. The only difference is the
|
|
8
8
|
* code body: instead of dispatching through `generator.generate(...)`
|
|
9
9
|
* to produce componentCode, the operator supplies the bytes directly
|
|
10
10
|
* and the handler persists them verbatim.
|
|
@@ -41,10 +41,11 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
41
41
|
import { z } from "zod";
|
|
42
42
|
import { assertContractNoRetiredFields } from "../renders/assert-contract-no-retired-fields.js";
|
|
43
43
|
import { assertGadgetsRegistered } from "../renders/assert-gadgets.js";
|
|
44
|
-
import {
|
|
44
|
+
import { admitGeneratorBuild } from "../renders/index.js";
|
|
45
|
+
import { mirrorIntoCache } from "./cache-mirror.js";
|
|
45
46
|
import { defineHandler } from "../types.js";
|
|
46
47
|
import { resolveEffectiveAppId } from "./app-access.js";
|
|
47
|
-
import { DirectionScopeWithoutDigestError } from "./errors.js";
|
|
48
|
+
import { ClonedFromRefusedError, DirectionScopeWithoutDigestError } from "./errors.js";
|
|
48
49
|
import { findNearDuplicatePersona, normalizePersona } from "./persona-normalization.js";
|
|
49
50
|
const opsInputSchema = opsRegisterBlueprintInputSchema.shape;
|
|
50
51
|
const opsOutputSchema = z.object({
|
|
@@ -60,7 +61,7 @@ const opsOutputSchema = z.object({
|
|
|
60
61
|
const USER_SOURCE = { kind: "user" };
|
|
61
62
|
/**
|
|
62
63
|
* The registration body both entries share: app resolution, the
|
|
63
|
-
* contract gates, the durable row, the cache mirror, the default
|
|
64
|
+
* contract gates, the durable row, the cache mirror, the operator-default mark and
|
|
64
65
|
* the event. The two entries differ only in the provenance they pass.
|
|
65
66
|
*/
|
|
66
67
|
function makeRegisterCore(deps) {
|
|
@@ -134,6 +135,18 @@ function makeRegisterCore(deps) {
|
|
|
134
135
|
throw new DirectionScopeWithoutDigestError();
|
|
135
136
|
}
|
|
136
137
|
const blueprintId = mintBlueprintId();
|
|
138
|
+
// ggui#1570 — a copy (`clonedFrom`, the door's input member, which the
|
|
139
|
+
// in-process generated-bytes entry parses too) names another row of this
|
|
140
|
+
// app that the store holds. Checked after the id is minted (a copy never
|
|
141
|
+
// names itself) and before anything is persisted. The cache mirror's own
|
|
142
|
+
// durable write-through, when it writes to a store other than this one,
|
|
143
|
+
// does not carry it: that copy serves re-mint, which ignores provenance.
|
|
144
|
+
if (parsed.clonedFrom !== undefined) {
|
|
145
|
+
const parentId = parsed.clonedFrom;
|
|
146
|
+
const parent = parentId.length > 0 && parentId !== blueprintId ? await deps.blueprintStore.get(parentId) : null;
|
|
147
|
+
if (parent === null || parent.appId !== appId)
|
|
148
|
+
throw new ClonedFromRefusedError(parentId);
|
|
149
|
+
}
|
|
137
150
|
// ONE variance for BOTH stores. The cache row's exact key is
|
|
138
151
|
// `variantKey(variance)`; omitting it on the cache call filed every
|
|
139
152
|
// variant under the default-variant key, where an earlier registration
|
|
@@ -155,6 +168,10 @@ function makeRegisterCore(deps) {
|
|
|
155
168
|
// row here, cache mirror below): the user arm for operator-
|
|
156
169
|
// supplied bytes, the llm arm for engine-generated ones.
|
|
157
170
|
source: provenance.source,
|
|
171
|
+
// ggui#1280 — the minting build, on a generation mint's bytes only.
|
|
172
|
+
...(provenance.build !== undefined ? { build: provenance.build } : {}),
|
|
173
|
+
// ggui#1570 — provenance about the row: the row whose bytes it copies.
|
|
174
|
+
...(parsed.clonedFrom !== undefined ? { clonedFrom: parsed.clonedFrom } : {}),
|
|
158
175
|
variance,
|
|
159
176
|
createdAt: now(),
|
|
160
177
|
createdBy: "operator",
|
|
@@ -178,41 +195,52 @@ function makeRegisterCore(deps) {
|
|
|
178
195
|
parsed.seedPrompt ??
|
|
179
196
|
normalizedPersona ??
|
|
180
197
|
`operator-registered blueprint (${blueprintId})`;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
:
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
198
|
+
// ggui#1497 — ONE id per registration: the cache row serves the
|
|
199
|
+
// durable row's id (see `mirrorIntoCache` for what else it writes).
|
|
200
|
+
await mirrorIntoCache({
|
|
201
|
+
cacheRegistry: deps.cacheRegistry,
|
|
202
|
+
writerStore: deps.blueprintStore,
|
|
203
|
+
appId,
|
|
204
|
+
blueprintId,
|
|
205
|
+
input: {
|
|
206
|
+
kind: "template",
|
|
207
|
+
contract,
|
|
208
|
+
intent: intentForCache,
|
|
209
|
+
// ggui#1275 — an explicit intent or a seed prompt states the
|
|
210
|
+
// UI's task. A persona describes the agent and the placeholder
|
|
211
|
+
// describes nothing: both are stand-ins the matcher's judge
|
|
212
|
+
// never sees.
|
|
213
|
+
intentSource: parsed.intent !== undefined || parsed.seedPrompt !== undefined
|
|
214
|
+
? "authored"
|
|
215
|
+
: "fallback",
|
|
216
|
+
// ggui#1427 — the fit facts `fits()` reads before the judge
|
|
217
|
+
// ranks this row. Absent inputs write nothing (not-evaluated).
|
|
218
|
+
...(parsed.judgedCanvases !== undefined ? { judgedCanvases: parsed.judgedCanvases } : {}),
|
|
219
|
+
...(parsed.aestheticPreset !== undefined ? { aestheticPreset: parsed.aestheticPreset } : {}),
|
|
220
|
+
...(parsed.directionDigest !== undefined ? { directionDigest: parsed.directionDigest } : {}),
|
|
221
|
+
...(parsed.directionDigest !== undefined && parsed.directionScope !== undefined
|
|
222
|
+
? { directionScope: parsed.directionScope }
|
|
223
|
+
: {}),
|
|
224
|
+
componentCode,
|
|
225
|
+
// ggui#1493 — the authored form of `componentCode`, when the
|
|
226
|
+
// caller has one (the in-process generated-bytes path only).
|
|
227
|
+
// The registry persists its hash and body only when a code
|
|
228
|
+
// store is bound and the pair is not byte-identical.
|
|
229
|
+
...(provenance.sourceCode !== undefined ? { sourceCode: provenance.sourceCode } : {}),
|
|
230
|
+
// Same provenance as the MVB row above — one call, one
|
|
231
|
+
// provenance claim across both stores.
|
|
232
|
+
source: provenance.source,
|
|
233
|
+
// ggui#1280 — the same stamp, onto the durable row a mirror
|
|
234
|
+
// writes through to (never onto its vector-store row).
|
|
235
|
+
...(provenance.build !== undefined ? { build: provenance.build } : {}),
|
|
236
|
+
// The cache row MUST carry the same variance as the MVB row —
|
|
237
|
+
// its exact key is `variantKey(variance)`.
|
|
238
|
+
variance,
|
|
239
|
+
// An operator invoked this tool. Without it the durable
|
|
240
|
+
// record would claim the standard agent flow minted a row
|
|
241
|
+
// that is retained permanently.
|
|
242
|
+
createdBy: "operator",
|
|
243
|
+
},
|
|
216
244
|
});
|
|
217
245
|
}
|
|
218
246
|
catch (err) {
|
|
@@ -235,7 +263,7 @@ function makeRegisterCore(deps) {
|
|
|
235
263
|
}
|
|
236
264
|
}
|
|
237
265
|
}
|
|
238
|
-
// 4.
|
|
266
|
+
// 4. Mark as operator default when requested.
|
|
239
267
|
if (parsed.setAsOperatorDefault === true) {
|
|
240
268
|
await deps.blueprintStore.setOperatorDefault(blueprintId);
|
|
241
269
|
}
|
|
@@ -268,7 +296,7 @@ export function createGguiOpsRegisterBlueprintHandler(deps) {
|
|
|
268
296
|
name: "ggui_ops_register_blueprint",
|
|
269
297
|
title: "Register blueprint",
|
|
270
298
|
audience: ["ops"],
|
|
271
|
-
description: "Register a pre-built blueprint variant (operator-supplied componentCode bytes, no LLM dispatch). Sibling of `ggui_ops_generate_blueprint` — same persistence + dual-write semantics, same variance + default
|
|
299
|
+
description: "Register a pre-built blueprint variant (operator-supplied componentCode bytes, no LLM dispatch). Sibling of `ggui_ops_generate_blueprint` — same persistence + dual-write semantics, same variance + operator-default mark behavior (the mark orders blueprint listings; it does not decide which blueprint serves a render). Use for fixture seeding, export/reimport round-trips, and manual recovery. Returns `{blueprintId, codeHash, source}` where `source` is always `{kind: 'user'}` — hand-supplied bytes carry no engine claim, so none is recorded. App-scoped variant curation for an app you operate — distinct from the personal saved-blueprint library (the _my_ tools).",
|
|
272
300
|
inputSchema: opsInputSchema,
|
|
273
301
|
outputSchema: opsOutputSchema,
|
|
274
302
|
async handler(rawInput, ctx) {
|
|
@@ -289,10 +317,12 @@ export function createGguiOpsRegisterBlueprintHandler(deps) {
|
|
|
289
317
|
* with the authored source they were compiled from, in-process.
|
|
290
318
|
*
|
|
291
319
|
* Same body as `ggui_ops_register_blueprint` (one durable row, one cache
|
|
292
|
-
* mirror, the same gates and variance), with
|
|
293
|
-
* is the generation's `llm` arm
|
|
294
|
-
*
|
|
295
|
-
* (`ggui_get_render_source`, save-to-library)
|
|
320
|
+
* mirror, the same gates and variance), with three differences: provenance
|
|
321
|
+
* is the generation's `llm` arm; the authored source reaches the cache
|
|
322
|
+
* registry, so a render that reuses the registration serves it
|
|
323
|
+
* (`ggui_get_render_source`, save-to-library); and the generation's build,
|
|
324
|
+
* when the caller passes one, is stamped on the durable rows (ggui#1280).
|
|
325
|
+
* It is NOT an MCP tool and
|
|
296
326
|
* is on no wire: the public operator door stays source-free, because it
|
|
297
327
|
* cannot verify that supplied source compiles to the supplied code.
|
|
298
328
|
*
|
|
@@ -307,9 +337,11 @@ export function createRegisterGeneratedBlueprint(deps) {
|
|
|
307
337
|
if (generated.sourceCode.length === 0) {
|
|
308
338
|
throw new Error("registerGeneratedBlueprint: sourceCode must be the non-empty authored source componentCode was compiled from");
|
|
309
339
|
}
|
|
340
|
+
const build = admitGeneratorBuild(source, generated.build);
|
|
310
341
|
const { blueprintId, codeHash } = await registerVariant(parsed, ctx, {
|
|
311
342
|
source,
|
|
312
343
|
sourceCode: generated.sourceCode,
|
|
344
|
+
...(build !== undefined ? { build } : {}),
|
|
313
345
|
});
|
|
314
346
|
return { blueprintId, codeHash, source };
|
|
315
347
|
};
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Patches the two mutable surfaces of a blueprint:
|
|
5
5
|
*
|
|
6
|
-
* 1. `isOperatorDefault` —
|
|
7
|
-
* blueprint's `(appId, contractHash)` group
|
|
6
|
+
* 1. `isOperatorDefault` — mark as the operator default for the
|
|
7
|
+
* blueprint's `(appId, contractHash)` group (orders listings; no
|
|
8
|
+
* render path reads it to choose what serves). The store
|
|
8
9
|
* automatically clears any prior default in the same group
|
|
9
10
|
* (see `BlueprintStore.setOperatorDefault`).
|
|
10
11
|
* 2. `variance` — partial merge into the persisted variance. Keys
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/update.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/update.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAGL,KAAK,iBAAiB,EAGvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,cAAc,EACf,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AASxF;;;;;;;;;GASG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,IAAI,EAAG,wBAAwB,CAAU;gBACtC,WAAW,EAAE,MAAM;CAMhC;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CACzD;AAuCD,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,0BAA0B;;;;;;;;;;;GAwEjC"}
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Patches the two mutable surfaces of a blueprint:
|
|
5
5
|
*
|
|
6
|
-
* 1. `isOperatorDefault` —
|
|
7
|
-
* blueprint's `(appId, contractHash)` group
|
|
6
|
+
* 1. `isOperatorDefault` — mark as the operator default for the
|
|
7
|
+
* blueprint's `(appId, contractHash)` group (orders listings; no
|
|
8
|
+
* render path reads it to choose what serves). The store
|
|
8
9
|
* automatically clears any prior default in the same group
|
|
9
10
|
* (see `BlueprintStore.setOperatorDefault`).
|
|
10
11
|
* 2. `variance` — partial merge into the persisted variance. Keys
|
|
@@ -91,7 +92,7 @@ export function createGguiOpsUpdateBlueprintHandler(deps) {
|
|
|
91
92
|
name: 'ggui_ops_update_blueprint',
|
|
92
93
|
title: 'Update blueprint',
|
|
93
94
|
audience: ['ops'],
|
|
94
|
-
description: 'Patch the mutable surface of an existing blueprint:
|
|
95
|
+
description: 'Patch the mutable surface of an existing blueprint: set the operator-default mark (it orders blueprint listings and is shown to operators; it does not decide which blueprint serves a render) + merge variance tags. Immutable fields (contractHash, appId, codeS3Url, codeHash, source, createdAt, createdBy) are absent from the schema — to "replace" a row, delete + re-generate. Partial-merge semantics: supplied variance keys overwrite, omitted keys preserve. Empty-string persona is removal. App-scoped variant curation for an app you operate — distinct from the personal saved-blueprint library (the _my_ tools).',
|
|
95
96
|
inputSchema: opsInputSchema,
|
|
96
97
|
outputSchema: opsOutputSchema,
|
|
97
98
|
async handler(rawInput, ctx) {
|
|
@@ -23,10 +23,13 @@
|
|
|
23
23
|
* proposed contract is the safety valve when a flagged surface is one
|
|
24
24
|
* the user must directly see or act on.
|
|
25
25
|
*
|
|
26
|
-
* Pure — no store, no LLM. Compares
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
26
|
+
* Pure — no store, no LLM. Compares declared key-SETS, plus ONE thing
|
|
27
|
+
* inside a shared action: the members that change what the runtime does
|
|
28
|
+
* with a gesture ({@link LOAD_BEARING_ACTION_MEMBERS}). Every other
|
|
29
|
+
* difference WITHIN a shared surface (a relabeled action, an `id` vs
|
|
30
|
+
* `id+done` payload schema) is tolerated, because atomic reuse hands the
|
|
31
|
+
* agent the cached contract and it drives that contract, not its own
|
|
32
|
+
* draft.
|
|
30
33
|
*/
|
|
31
34
|
import type { DataContract } from '@ggui-ai/protocol';
|
|
32
35
|
/** The request-declared surfaces a candidate fails to cover. Empty
|
|
@@ -37,7 +40,23 @@ export interface CoverageGap {
|
|
|
37
40
|
readonly context: readonly string[];
|
|
38
41
|
readonly streams: readonly string[];
|
|
39
42
|
readonly gadgets: readonly string[];
|
|
43
|
+
/**
|
|
44
|
+
* `<action>.<member>` for every load-bearing member the request declares
|
|
45
|
+
* on an action BOTH contracts carry, where the candidate's entry does not
|
|
46
|
+
* say the same (ggui#1428). An action the candidate lacks altogether is in
|
|
47
|
+
* {@link actions}, never here.
|
|
48
|
+
*/
|
|
49
|
+
readonly actionMembers: readonly string[];
|
|
40
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* The action-entry members that change what the runtime DOES with a gesture,
|
|
53
|
+
* as opposed to how the action reads: `oneShot` arms the single-dispatch
|
|
54
|
+
* guard, `confirm` asks before firing, `nextStep` names the tool the agent is
|
|
55
|
+
* routed to. A stored card that lacks one the draft declares serves a card
|
|
56
|
+
* without that behaviour, so the agent is told. `label`, `description`,
|
|
57
|
+
* `icon`, `example` and `schema` stay tolerated differences.
|
|
58
|
+
*/
|
|
59
|
+
export declare const LOAD_BEARING_ACTION_MEMBERS: readonly ["oneShot", "confirm", "nextStep"];
|
|
41
60
|
/**
|
|
42
61
|
* Compute the surfaces the request declares that the candidate does NOT.
|
|
43
62
|
* A wholly-empty gap means the candidate covers the request.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blueprint-coverage.d.ts","sourceRoot":"","sources":["../../src/renders/blueprint-coverage.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"blueprint-coverage.d.ts","sourceRoot":"","sources":["../../src/renders/blueprint-coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD;4DAC4D;AAC5D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,6CAA8C,CAAC;AA6CvF;;;GAGG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,YAAY,EACvB,OAAO,EAAE,YAAY,GACpB,WAAW,CAYb;AAED;2DAC2D;AAC3D,wBAAgB,MAAM,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAU9E"}
|
|
@@ -23,12 +23,50 @@
|
|
|
23
23
|
* proposed contract is the safety valve when a flagged surface is one
|
|
24
24
|
* the user must directly see or act on.
|
|
25
25
|
*
|
|
26
|
-
* Pure — no store, no LLM. Compares
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
26
|
+
* Pure — no store, no LLM. Compares declared key-SETS, plus ONE thing
|
|
27
|
+
* inside a shared action: the members that change what the runtime does
|
|
28
|
+
* with a gesture ({@link LOAD_BEARING_ACTION_MEMBERS}). Every other
|
|
29
|
+
* difference WITHIN a shared surface (a relabeled action, an `id` vs
|
|
30
|
+
* `id+done` payload schema) is tolerated, because atomic reuse hands the
|
|
31
|
+
* agent the cached contract and it drives that contract, not its own
|
|
32
|
+
* draft.
|
|
30
33
|
*/
|
|
31
34
|
import { listContractGadgets } from '@ggui-ai/protocol';
|
|
35
|
+
/**
|
|
36
|
+
* The action-entry members that change what the runtime DOES with a gesture,
|
|
37
|
+
* as opposed to how the action reads: `oneShot` arms the single-dispatch
|
|
38
|
+
* guard, `confirm` asks before firing, `nextStep` names the tool the agent is
|
|
39
|
+
* routed to. A stored card that lacks one the draft declares serves a card
|
|
40
|
+
* without that behaviour, so the agent is told. `label`, `description`,
|
|
41
|
+
* `icon`, `example` and `schema` stay tolerated differences.
|
|
42
|
+
*/
|
|
43
|
+
export const LOAD_BEARING_ACTION_MEMBERS = ['oneShot', 'confirm', 'nextStep'];
|
|
44
|
+
/**
|
|
45
|
+
* Members the request DECLARES on `name` that the candidate's entry does not
|
|
46
|
+
* match. One direction, like the rest of coverage: a boolean member counts as
|
|
47
|
+
* declared only when `true` (`false` and absent both mean "off"), `nextStep`
|
|
48
|
+
* when present. A candidate that is stricter than the request (it carries a
|
|
49
|
+
* member the request does not) is not a gap. That holds for `nextStep` too,
|
|
50
|
+
* because the case that would matter there is already refused elsewhere: a
|
|
51
|
+
* stored `nextStep` naming a tool the requesting agent does not declare makes
|
|
52
|
+
* the candidate unfulfillable, and `isFulfillable` declines it before it is
|
|
53
|
+
* ever proposed (`blueprint-fulfillability.ts`).
|
|
54
|
+
*/
|
|
55
|
+
function mismatchedActionMembers(request, candidate) {
|
|
56
|
+
const out = [];
|
|
57
|
+
for (const [name, wanted] of Object.entries(request.actionSpec ?? {})) {
|
|
58
|
+
const stored = candidate.actionSpec?.[name];
|
|
59
|
+
if (stored === undefined)
|
|
60
|
+
continue;
|
|
61
|
+
if (wanted.oneShot === true && stored.oneShot !== true)
|
|
62
|
+
out.push(`${name}.oneShot`);
|
|
63
|
+
if (wanted.confirm === true && stored.confirm !== true)
|
|
64
|
+
out.push(`${name}.confirm`);
|
|
65
|
+
if (wanted.nextStep !== undefined && stored.nextStep !== wanted.nextStep)
|
|
66
|
+
out.push(`${name}.nextStep`);
|
|
67
|
+
}
|
|
68
|
+
return out.sort();
|
|
69
|
+
}
|
|
32
70
|
function keySet(map) {
|
|
33
71
|
return new Set(Object.keys(map ?? {}));
|
|
34
72
|
}
|
|
@@ -51,6 +89,7 @@ export function coverageGap(candidate, request) {
|
|
|
51
89
|
context: missing(keySet(request.contextSpec), keySet(candidate.contextSpec)),
|
|
52
90
|
streams: missing(keySet(request.streamSpec), keySet(candidate.streamSpec)),
|
|
53
91
|
gadgets: missing(gadgetIdSet(request), gadgetIdSet(candidate)),
|
|
92
|
+
actionMembers: mismatchedActionMembers(request, candidate),
|
|
54
93
|
};
|
|
55
94
|
}
|
|
56
95
|
/** True iff `candidate` declares every surface `request` declares —
|
|
@@ -61,5 +100,6 @@ export function covers(candidate, request) {
|
|
|
61
100
|
gap.props.length === 0 &&
|
|
62
101
|
gap.context.length === 0 &&
|
|
63
102
|
gap.streams.length === 0 &&
|
|
64
|
-
gap.gadgets.length === 0
|
|
103
|
+
gap.gadgets.length === 0 &&
|
|
104
|
+
gap.actionMembers.length === 0);
|
|
65
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blueprint-durability.d.ts","sourceRoot":"","sources":["../../src/renders/blueprint-durability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,IAAI,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE9E;;;;;GAKG;AACH,MAAM,MAAM,wBAAwB,GAChC,gCAAgC,GAChC,6BAA6B,GAC7B,+BAA+B,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,2BAA2B;IACtC,sEAAsE;;IAEtE,gEAAgE;;IAEhE;;;;;;;OAOG;;CAEwD,CAAC;AAW9D;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,SAAS,GAAE,gBAAgB,CAAC,WAAW,CAAW,GACjD,gBAAgB,
|
|
1
|
+
{"version":3,"file":"blueprint-durability.d.ts","sourceRoot":"","sources":["../../src/renders/blueprint-durability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,IAAI,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE9E;;;;;GAKG;AACH,MAAM,MAAM,wBAAwB,GAChC,gCAAgC,GAChC,6BAA6B,GAC7B,+BAA+B,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,2BAA2B;IACtC,sEAAsE;;IAEtE,gEAAgE;;IAEhE;;;;;;;OAOG;;CAEwD,CAAC;AAW9D;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,SAAS,GAAE,gBAAgB,CAAC,WAAW,CAAW,GACjD,gBAAgB,CAiClB;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,uBAAuB,GAAG,SAAS,EACzC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,iBAAiB,EAC5B,SAAS,GAAE,gBAAgB,CAAC,WAAW,CAAW,GACjD,OAAO,CAAC,IAAI,CAAC,CA0Df"}
|
|
@@ -56,6 +56,11 @@ export function projectDurableBlueprint(blueprint, appId, codeHash, createdBy =
|
|
|
56
56
|
...(blueprint.sourceCodeHash !== undefined
|
|
57
57
|
? { sourceCodeHash: blueprint.sourceCodeHash }
|
|
58
58
|
: {}),
|
|
59
|
+
// ggui#1280 — the minting engine's build, admitted at registration.
|
|
60
|
+
// Written once here at mint (a dedup never reaches this projection) and
|
|
61
|
+
// never rewritten. The registry's vector-store row carries the same
|
|
62
|
+
// value (ggui#1476).
|
|
63
|
+
...(blueprint.build !== undefined ? { build: blueprint.build } : {}),
|
|
59
64
|
};
|
|
60
65
|
}
|
|
61
66
|
/**
|
|
@@ -180,7 +180,35 @@ export interface MatchBlueprintOptions {
|
|
|
180
180
|
* stability-sensitive caller cannot afford (ggui#607).
|
|
181
181
|
*/
|
|
182
182
|
readonly disableSemantic?: boolean;
|
|
183
|
+
/**
|
|
184
|
+
* ggui#1568 — WHY `disableSemantic` is set, so the trace never names a
|
|
185
|
+
* cause that did not hold. `'exact-only-policy'` (the default) is the
|
|
186
|
+
* ggui#607 reuse policy. `'exclusion-unavailable'` means the deployment
|
|
187
|
+
* could not say which rows are reserved from the semantic tier
|
|
188
|
+
* ({@link excludeFromSemantic}), so it turned the tier off rather than
|
|
189
|
+
* risk offering one. Read only when `disableSemantic` is true.
|
|
190
|
+
*/
|
|
191
|
+
readonly disableSemanticCause?: 'exact-only-policy' | 'exclusion-unavailable';
|
|
192
|
+
/**
|
|
193
|
+
* ggui#1568 — rows the deployment reserves from the semantic tier, each
|
|
194
|
+
* named by {@link semanticExclusionKey}. A named row is dropped straight
|
|
195
|
+
* after retrieval, so it is never offered to the judge, never returned as
|
|
196
|
+
* a candidate and never reused by similarity. It stays reachable by its
|
|
197
|
+
* exact key: exclusion governs how a row is FOUND, never whether it can be
|
|
198
|
+
* served to a request that names it. Retrieval over-fetches by the set's
|
|
199
|
+
* size, so the pool the judge ranks is still `topK` deep. A vector store
|
|
200
|
+
* that clamps its `topK` returns fewer rows than asked, and the pool is
|
|
201
|
+
* then shallower: fewer reuses, never a reserved row.
|
|
202
|
+
*/
|
|
203
|
+
readonly excludeFromSemantic?: ReadonlySet<string>;
|
|
183
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* ggui#1568 — the key {@link MatchBlueprintOptions.excludeFromSemantic}
|
|
207
|
+
* names a row by: its `(contractKey, variantKey)` pair, the same pair the
|
|
208
|
+
* exact tier resolves. Unambiguous by construction (JSON array), so no two
|
|
209
|
+
* different pairs share a key.
|
|
210
|
+
*/
|
|
211
|
+
export declare function semanticExclusionKey(contractKey: string, variantKey: string): string;
|
|
184
212
|
/**
|
|
185
213
|
* Walk the matcher and return the decision.
|
|
186
214
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blueprint-matcher.d.ts","sourceRoot":"","sources":["../../src/renders/blueprint-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAQ,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAC1F,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAML,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC3B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AACtF,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"blueprint-matcher.d.ts","sourceRoot":"","sources":["../../src/renders/blueprint-matcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,7 +14,17 @@ const EMPTY_GAP = {
|
|
|
14
14
|
context: [],
|
|
15
15
|
streams: [],
|
|
16
16
|
gadgets: [],
|
|
17
|
+
actionMembers: [],
|
|
17
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* ggui#1568 — the key {@link MatchBlueprintOptions.excludeFromSemantic}
|
|
21
|
+
* names a row by: its `(contractKey, variantKey)` pair, the same pair the
|
|
22
|
+
* exact tier resolves. Unambiguous by construction (JSON array), so no two
|
|
23
|
+
* different pairs share a key.
|
|
24
|
+
*/
|
|
25
|
+
export function semanticExclusionKey(contractKey, variantKey) {
|
|
26
|
+
return JSON.stringify([contractKey, variantKey]);
|
|
27
|
+
}
|
|
18
28
|
const DEFAULT_TOP_K = 20;
|
|
19
29
|
// The cosine gate before the judge — ONE FLOOR PER QUERY KIND, because the
|
|
20
30
|
// two kinds of query sit on two scales (ggui#606).
|
|
@@ -221,10 +231,13 @@ export async function matchBlueprint(deps, scope, query, options = {}) {
|
|
|
221
231
|
await ensured;
|
|
222
232
|
}
|
|
223
233
|
if (options.disableSemantic === true) {
|
|
224
|
-
//
|
|
225
|
-
//
|
|
226
|
-
//
|
|
227
|
-
|
|
234
|
+
// The semantic tier is switched off for this request: the exact-only
|
|
235
|
+
// reuse policy (ggui#607), or a deployment that cannot say which rows
|
|
236
|
+
// are reserved from it (ggui#1568). Report the miss, naming which,
|
|
237
|
+
// without spending the retrieval or the judge call.
|
|
238
|
+
const reason = options.disableSemanticCause === 'exclusion-unavailable'
|
|
239
|
+
? 'no-match: no canonical match, and similar-interface reuse is unavailable for this request — a new interface will be generated'
|
|
240
|
+
: 'exact-only policy: no canonical match — a new interface will be generated';
|
|
228
241
|
emit({ decision: 'no-match', strategy: 'semantic', reason, candidates: [] });
|
|
229
242
|
return { strategy: 'no-match', reason, candidates: [] };
|
|
230
243
|
}
|
|
@@ -236,6 +249,9 @@ export async function matchBlueprint(deps, scope, query, options = {}) {
|
|
|
236
249
|
// Miss buckets distinguish cosine-gate, no-LLM, judge-declined,
|
|
237
250
|
// low-confidence, defense.
|
|
238
251
|
let candidates = [];
|
|
252
|
+
const excluded = options.excludeFromSemantic;
|
|
253
|
+
const excludedCount = excluded?.size ?? 0;
|
|
254
|
+
let droppedByExclusion = 0;
|
|
239
255
|
try {
|
|
240
256
|
// ggui#606: compose the query the way stored vectors are composed
|
|
241
257
|
// (`composeEmbeddingInput(contract, intent)`), so a candidate is scored
|
|
@@ -244,7 +260,14 @@ export async function matchBlueprint(deps, scope, query, options = {}) {
|
|
|
244
260
|
const ragArg = query.contract !== undefined
|
|
245
261
|
? { intent: trimmedIntent, contract: query.contract }
|
|
246
262
|
: { intent: trimmedIntent };
|
|
247
|
-
|
|
263
|
+
const retrieved = await findBlueprintsByEmbedding(deps.registry, scope, ragArg, { kind, topK: topK + excludedCount });
|
|
264
|
+
// ggui#1568 — a reserved row leaves here, before the cosine gate, the
|
|
265
|
+
// judge, the trace and the result: nothing downstream ever sees it.
|
|
266
|
+
const kept = excluded === undefined || excludedCount === 0
|
|
267
|
+
? retrieved
|
|
268
|
+
: retrieved.filter((c) => !excluded.has(semanticExclusionKey(c.blueprint.contractKey, c.blueprint.variantKey)));
|
|
269
|
+
droppedByExclusion = retrieved.length - kept.length;
|
|
270
|
+
candidates = kept.slice(0, topK);
|
|
248
271
|
}
|
|
249
272
|
catch (err) {
|
|
250
273
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -258,11 +281,18 @@ export async function matchBlueprint(deps, scope, query, options = {}) {
|
|
|
258
281
|
return { strategy: 'no-match', reason, candidates: [] };
|
|
259
282
|
}
|
|
260
283
|
if (candidates.length === 0) {
|
|
261
|
-
|
|
284
|
+
// ggui#1568 — "first registration" is false when rows were retrieved and
|
|
285
|
+
// every one was reserved; the reason says which it was.
|
|
286
|
+
const reason = droppedByExclusion > 0
|
|
287
|
+
? 'no-match: no saved interface is available for reuse — a new one will be generated'
|
|
288
|
+
: 'no-match: no candidates in scope — first registration of this kind';
|
|
289
|
+
const traceReason = droppedByExclusion > 0
|
|
290
|
+
? `no-match: ${droppedByExclusion} candidates retrieved, every one reserved from the semantic tier by the deployment`
|
|
291
|
+
: reason;
|
|
262
292
|
emit({
|
|
263
293
|
decision: 'no-match',
|
|
264
294
|
strategy: 'semantic',
|
|
265
|
-
reason,
|
|
295
|
+
reason: traceReason,
|
|
266
296
|
candidates: [],
|
|
267
297
|
});
|
|
268
298
|
return { strategy: 'no-match', reason, candidates: [] };
|
|
@@ -463,6 +493,8 @@ function coverageGapNote(gap) {
|
|
|
463
493
|
parts.push(`streams: ${gap.streams.join(', ')}`);
|
|
464
494
|
if (gap.gadgets.length > 0)
|
|
465
495
|
parts.push(`gadgets: ${gap.gadgets.join(', ')}`);
|
|
496
|
+
if (gap.actionMembers.length > 0)
|
|
497
|
+
parts.push(`action members: ${gap.actionMembers.join(', ')}`);
|
|
466
498
|
if (parts.length === 0)
|
|
467
499
|
return '';
|
|
468
500
|
return ` [coverage gap — the request declares surfaces this cached UI lacks (${parts.join('; ')}); agent override is the safety valve]`;
|