@ggui-ai/mcp-server-handlers 0.25.0 → 0.27.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 +201 -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
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @ggui-ai/mcp-server-handlers
|
|
2
2
|
|
|
3
|
-
MCP tool handler logic for the **
|
|
3
|
+
MCP tool handler logic for the **GGUI protocol**.
|
|
4
4
|
|
|
5
|
-
This package implements the actual behavior behind every
|
|
5
|
+
This package implements the actual behavior behind every GGUI MCP tool — render
|
|
6
6
|
lifecycle, the contract handshake, UI emission, blueprint management, threads, app
|
|
7
7
|
discovery, and the operator (`ggui_ops_*`) tools. The handlers are written purely
|
|
8
8
|
over the seam interfaces in
|
package/dist/credits/index.d.ts
CHANGED
|
@@ -25,6 +25,6 @@
|
|
|
25
25
|
*/
|
|
26
26
|
export { createGetCreditBalanceHandler, } from './get-credit-balance.js';
|
|
27
27
|
export type { CreditBalanceSource, CreditBalanceView, GetCreditBalanceDeps, GetCreditBalanceOutput, } from './get-credit-balance.js';
|
|
28
|
-
export { createListCreditTransactionsHandler, } from './list-credit-transactions.js';
|
|
29
|
-
export type { CreditTransactionSource, CreditTransactionView, ListCreditTransactionsDeps, ListCreditTransactionsOutput, } from './list-credit-transactions.js';
|
|
28
|
+
export { createListCreditTransactionsHandler, KNOWN_CREDIT_TRANSACTION_KINDS, } from './list-credit-transactions.js';
|
|
29
|
+
export type { CreditTransactionKind, CreditTransactionSource, CreditTransactionView, KnownCreditTransactionKind, ListCreditTransactionsDeps, ListCreditTransactionsOutput, } from './list-credit-transactions.js';
|
|
30
30
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/credits/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EACL,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,mCAAmC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/credits/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EACL,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,mCAAmC,EACnC,8BAA8B,GAC/B,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,+BAA+B,CAAC"}
|
package/dist/credits/index.js
CHANGED
|
@@ -24,4 +24,4 @@
|
|
|
24
24
|
* side-channel — same posture as the blueprint family.
|
|
25
25
|
*/
|
|
26
26
|
export { createGetCreditBalanceHandler, } from './get-credit-balance.js';
|
|
27
|
-
export { createListCreditTransactionsHandler, } from './list-credit-transactions.js';
|
|
27
|
+
export { createListCreditTransactionsHandler, KNOWN_CREDIT_TRANSACTION_KINDS, } from './list-credit-transactions.js';
|
|
@@ -34,9 +34,28 @@ export interface CreditTransactionSource {
|
|
|
34
34
|
nextCursor?: string;
|
|
35
35
|
}>;
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* The ledger kinds this package names (ggui#1532). The vocabulary is OPEN: a
|
|
39
|
+
* deployment's ledger may carry kinds not listed here, and a reader MUST accept
|
|
40
|
+
* one it does not know, keep it as named, and never read it as a render charge.
|
|
41
|
+
* Listing a kind here documents it; it is not the set of kinds that may appear.
|
|
42
|
+
*/
|
|
43
|
+
export declare const KNOWN_CREDIT_TRANSACTION_KINDS: readonly ["free_credit", "render_charge", "topup", "refund"];
|
|
44
|
+
/** One of the kinds this package names. */
|
|
45
|
+
export type KnownCreditTransactionKind = (typeof KNOWN_CREDIT_TRANSACTION_KINDS)[number];
|
|
46
|
+
/**
|
|
47
|
+
* A ledger entry's kind: a known kind, or any other non-empty kind a
|
|
48
|
+
* deployment names. The `string & {}` arm keeps the set OPEN while editors
|
|
49
|
+
* still offer the known kinds and a `switch` can name them (it needs a default).
|
|
50
|
+
*/
|
|
51
|
+
export type CreditTransactionKind = KnownCreditTransactionKind | (string & {});
|
|
37
52
|
export interface CreditTransactionView {
|
|
38
53
|
readonly transactionId: string;
|
|
39
|
-
|
|
54
|
+
/**
|
|
55
|
+
* The entry's kind: one of {@link KNOWN_CREDIT_TRANSACTION_KINDS}, or a kind
|
|
56
|
+
* the deployment names that this package does not. Open vocabulary.
|
|
57
|
+
*/
|
|
58
|
+
readonly kind: CreditTransactionKind;
|
|
40
59
|
readonly deltaCents: number;
|
|
41
60
|
readonly balanceAfterCents: number;
|
|
42
61
|
readonly reason: string;
|
|
@@ -58,12 +77,7 @@ export declare function createListCreditTransactionsHandler(deps: ListCreditTran
|
|
|
58
77
|
}, {
|
|
59
78
|
transactions: z.ZodArray<z.ZodObject<{
|
|
60
79
|
transactionId: z.ZodString;
|
|
61
|
-
kind: z.
|
|
62
|
-
free_credit: "free_credit";
|
|
63
|
-
render_charge: "render_charge";
|
|
64
|
-
topup: "topup";
|
|
65
|
-
refund: "refund";
|
|
66
|
-
}>;
|
|
80
|
+
kind: z.ZodString;
|
|
67
81
|
deltaCents: z.ZodNumber;
|
|
68
82
|
balanceAfterCents: z.ZodNumber;
|
|
69
83
|
reason: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-credit-transactions.d.ts","sourceRoot":"","sources":["../../src/credits/list-credit-transactions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,IAAI,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,oCAAoC;QACpC,KAAK,EAAE,MAAM,CAAC;QACd,4EAA4E;QAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC;QACV,YAAY,EAAE,qBAAqB,EAAE,CAAC;QACtC,6CAA6C;QAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"list-credit-transactions.d.ts","sourceRoot":"","sources":["../../src/credits/list-credit-transactions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,IAAI,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,oCAAoC;QACpC,KAAK,EAAE,MAAM,CAAC;QACd,4EAA4E;QAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC;QACV,YAAY,EAAE,qBAAqB,EAAE,CAAC;QACtC,6CAA6C;QAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AAED;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,8DAA+D,CAAC;AAE3G,2CAA2C;AAC3C,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,8BAA8B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzF;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,0BAA0B,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE/E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,kBAAkB,EAAE,uBAAuB,CAAC;CACtD;AA8BD,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,YAAY,EAAE,qBAAqB,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,0BAA0B;IAjChC,2BAA2B;;IAE3B,kEAAkE;;;;;;;;;;;;IAqBlE,oFAAoF;;;;;GAgDrF"}
|
|
@@ -17,6 +17,13 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { z } from 'zod';
|
|
19
19
|
import { defineHandler } from '../types.js';
|
|
20
|
+
/**
|
|
21
|
+
* The ledger kinds this package names (ggui#1532). The vocabulary is OPEN: a
|
|
22
|
+
* deployment's ledger may carry kinds not listed here, and a reader MUST accept
|
|
23
|
+
* one it does not know, keep it as named, and never read it as a render charge.
|
|
24
|
+
* Listing a kind here documents it; it is not the set of kinds that may appear.
|
|
25
|
+
*/
|
|
26
|
+
export const KNOWN_CREDIT_TRANSACTION_KINDS = ['free_credit', 'render_charge', 'topup', 'refund'];
|
|
20
27
|
const inputSchema = {
|
|
21
28
|
/** Default 20. Cap 100. */
|
|
22
29
|
limit: z.number().int().min(1).max(100).optional(),
|
|
@@ -26,7 +33,10 @@ const inputSchema = {
|
|
|
26
33
|
const outputSchema = {
|
|
27
34
|
transactions: z.array(z.object({
|
|
28
35
|
transactionId: z.string(),
|
|
29
|
-
kind: z
|
|
36
|
+
kind: z
|
|
37
|
+
.string()
|
|
38
|
+
.min(1)
|
|
39
|
+
.describe("The ledger entry's kind, an open vocabulary. Known kinds: 'free_credit', 'render_charge', 'topup', 'refund'. A deployment may add others: accept a kind you do not know, keep it as named, and never read it as a render charge."),
|
|
30
40
|
deltaCents: z.number().int(),
|
|
31
41
|
balanceAfterCents: z.number().int(),
|
|
32
42
|
reason: z.string(),
|
|
@@ -41,7 +51,7 @@ export function createListCreditTransactionsHandler(deps) {
|
|
|
41
51
|
name: 'ggui_ops_list_credit_transactions',
|
|
42
52
|
title: 'List credit transactions',
|
|
43
53
|
audience: ['ops'],
|
|
44
|
-
description: "Returns the calling user's credit transaction ledger, newest-first. Each row carries kind ('free_credit'
|
|
54
|
+
description: "Returns the calling user's credit transaction ledger, newest-first. Each row carries kind (an open vocabulary: known kinds are 'free_credit', 'render_charge', 'topup' and 'refund', and a deployment may add others; treat an unknown kind as a ledger entry of that name, never as a render charge), deltaCents (signed — positive for grants/topups, negative for charges), balanceAfterCents (snapshot at time of write), reason (human-readable), and optional relatedSessionId for render_charge rows. Default limit 20, cap 100; pass `cursor` from the previous response's `nextCursor` for paging.",
|
|
45
55
|
inputSchema,
|
|
46
56
|
outputSchema,
|
|
47
57
|
// No `allowedFor` — same toolset on every deployment kind. Callers
|
package/dist/index.d.ts
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
export * from "./blueprints/index.js";
|
|
17
17
|
export * from "./renders/index.js";
|
|
18
|
-
export { AuthRequiredError, HANDLER_FAILURE_MARKER, defineHandler, handlerFailure, isHandlerFailure, } from "./types.js";
|
|
19
|
-
export type { AudienceTag, EnvelopedHandlerDefinition, EnvelopeFor, HandlerContext, HandlerDefinition, HandlerFailure, ShapeOutput, SharedHandler, SharedHandlerOutputBound, SharedHandlerOutputData, SharedHandlerResult, } from "./types.js";
|
|
18
|
+
export { AuthRequiredError, HANDLER_FAILURE_MARKER, createSessionRowReads, defineHandler, handlerFailure, isHandlerFailure, readSessionRow, viewProofUseFor, } from "./types.js";
|
|
19
|
+
export type { AudienceTag, EnvelopedHandlerDefinition, EnvelopeFor, HandlerContext, HandlerDefinition, HandlerFailure, SessionRowReads, ShapeOutput, SharedHandler, SharedHandlerOutputBound, SharedHandlerOutputData, SharedHandlerResult, ViewProofDeclaration, ViewProofUse, } from "./types.js";
|
|
20
20
|
export * from "./threads/index.js";
|
|
21
21
|
export * from "./credits/index.js";
|
|
22
22
|
export * from "./app-discovery/index.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,aAAa,EACb,cAAc,EACd,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,WAAW,EACX,0BAA0B,EAC1B,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,WAAW,EACX,aAAa,EACb,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,GACb,MAAM,YAAY,CAAC;AAIpB,cAAc,oBAAoB,CAAC;AAInC,cAAc,oBAAoB,CAAC;AAInC,cAAc,0BAA0B,CAAC;AAIzC,cAAc,0BAA0B,CAAC;AAKzC,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
export * from "./blueprints/index.js";
|
|
17
17
|
export * from "./renders/index.js";
|
|
18
|
-
export { AuthRequiredError, HANDLER_FAILURE_MARKER, defineHandler, handlerFailure, isHandlerFailure, } from "./types.js";
|
|
18
|
+
export { AuthRequiredError, HANDLER_FAILURE_MARKER, createSessionRowReads, defineHandler, handlerFailure, isHandlerFailure, readSessionRow, viewProofUseFor, } from "./types.js";
|
|
19
19
|
// Persistent-chat handler family — thread storage and message
|
|
20
20
|
// history MCP tools. Thin over @ggui-ai/mcp-server-core ThreadStore.
|
|
21
21
|
// Available under `@ggui-ai/mcp-server-handlers/threads` subpath too.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How an ops writer mirrors its durable row into the cache registry
|
|
3
|
+
* (ggui#1497): under ONE id.
|
|
4
|
+
*
|
|
5
|
+
* `ggui_ops_register_blueprint` (with `createRegisterGeneratedBlueprint`,
|
|
6
|
+
* which shares its core) and `ggui_ops_generate_blueprint` each put the
|
|
7
|
+
* durable row first, then mirror it into the cache so the exact-key probe
|
|
8
|
+
* finds it. The mirror used to mint an id of its own, so a render served
|
|
9
|
+
* from that cache row recorded an id the writer's store never held. The
|
|
10
|
+
* mirror now takes the writer's id (`mintId`), and what else it writes
|
|
11
|
+
* depends on where re-mint reads:
|
|
12
|
+
*
|
|
13
|
+
* - The mirror's registry writes through to a durable store OTHER than the
|
|
14
|
+
* writer's (a server that keeps its re-mint store apart from the ops
|
|
15
|
+
* store): the full write-through runs, now under the shared id, so the
|
|
16
|
+
* store re-mint reads holds the row and the compiled body under the id
|
|
17
|
+
* the cache serves.
|
|
18
|
+
* - It writes through to the writer's OWN store: the row is already there
|
|
19
|
+
* under this id, and the store refuses a second put of it, so the mirror
|
|
20
|
+
* skips the row but still puts the compiled body into its code store,
|
|
21
|
+
* where re-mint reads it.
|
|
22
|
+
* - No durable store (a code store at most): nothing more is written; the
|
|
23
|
+
* writer's own store and body are what re-mint reads.
|
|
24
|
+
*
|
|
25
|
+
* The authored source still reaches a bound code store in every case
|
|
26
|
+
* (ggui#1493). A dedup is unchanged: an exact key already bound returns its
|
|
27
|
+
* existing id, and nothing more is written for it.
|
|
28
|
+
*/
|
|
29
|
+
import type { BlueprintStore } from "@ggui-ai/mcp-server-core";
|
|
30
|
+
import { type BlueprintRegistryDeps, type RegisterBlueprintInput, type RegisteredBlueprint } from "../renders/blueprint-registry.js";
|
|
31
|
+
export declare function mirrorIntoCache(args: {
|
|
32
|
+
/** The cache registry the writer mirrors into. */
|
|
33
|
+
readonly cacheRegistry: BlueprintRegistryDeps;
|
|
34
|
+
/** The store the writer already put the durable row in, under `blueprintId`. */
|
|
35
|
+
readonly writerStore: BlueprintStore;
|
|
36
|
+
readonly appId: string;
|
|
37
|
+
/** The writer's durable row id: the cache row takes it. */
|
|
38
|
+
readonly blueprintId: string;
|
|
39
|
+
readonly input: RegisterBlueprintInput;
|
|
40
|
+
}): Promise<RegisteredBlueprint>;
|
|
41
|
+
//# sourceMappingURL=cache-mirror.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-mirror.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/cache-mirror.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACzB,MAAM,kCAAkC,CAAC;AAE1C,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,kDAAkD;IAClD,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;IAC9C,gFAAgF;IAChF,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC;CACxC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAkB/B"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { registerBlueprint, } from "../renders/blueprint-registry.js";
|
|
2
|
+
export async function mirrorIntoCache(args) {
|
|
3
|
+
const durability = args.cacheRegistry.durability;
|
|
4
|
+
const sharesWriterStore = durability?.blueprintStore !== undefined && durability.blueprintStore === args.writerStore;
|
|
5
|
+
const deps = sharesWriterStore
|
|
6
|
+
? {
|
|
7
|
+
...args.cacheRegistry,
|
|
8
|
+
durability: durability.codeStore !== undefined ? { codeStore: durability.codeStore } : {},
|
|
9
|
+
}
|
|
10
|
+
: args.cacheRegistry;
|
|
11
|
+
const registered = await registerBlueprint(deps, args.appId, args.input, {
|
|
12
|
+
mintId: () => args.blueprintId,
|
|
13
|
+
});
|
|
14
|
+
const codeStore = durability?.codeStore;
|
|
15
|
+
if (sharesWriterStore && !registered.deduped && codeStore !== undefined && args.input.componentCode.length > 0) {
|
|
16
|
+
await codeStore.put(codeStore.hashOf(args.input.componentCode), args.input.componentCode);
|
|
17
|
+
}
|
|
18
|
+
return registered;
|
|
19
|
+
}
|
|
@@ -18,12 +18,23 @@
|
|
|
18
18
|
* a foreign `appId` input the authorizer denies surfaces the denial
|
|
19
19
|
* error before the row lookup ever runs.
|
|
20
20
|
*
|
|
21
|
+
* ## Out of reuse (ggui#1541)
|
|
22
|
+
*
|
|
23
|
+
* `ggui_ops_register_blueprint` and `ggui_ops_generate_blueprint` write a
|
|
24
|
+
* blueprint twice: the durable row, and a mirror in the cache registry, the
|
|
25
|
+
* store the handshake's exact-key probe matches from. So a delete removes
|
|
26
|
+
* both, the cache row first: a cache delete that fails fails the call
|
|
27
|
+
* before the durable row goes, and a retry completes it. An id whose
|
|
28
|
+
* durable row is already gone still has its cache row cleared in the
|
|
29
|
+
* caller's own app scope, which heals a row an earlier delete left behind.
|
|
30
|
+
*
|
|
21
31
|
* ## Audience
|
|
22
32
|
*
|
|
23
33
|
* `['ops']` — served on `/control`. NOT visible to agents on `/mcp`.
|
|
24
34
|
*/
|
|
25
35
|
import { z } from 'zod';
|
|
26
36
|
import type { BlueprintStore } from '@ggui-ai/mcp-server-core';
|
|
37
|
+
import { type BlueprintRegistryDeps } from '../renders/blueprint-registry.js';
|
|
27
38
|
import { type OpsBlueprintAppAuthorizer } from './app-access.js';
|
|
28
39
|
/**
|
|
29
40
|
* Deps for `ggui_ops_delete_blueprint`.
|
|
@@ -45,6 +56,13 @@ export interface GguiOpsDeleteBlueprintDeps {
|
|
|
45
56
|
* the target row belongs to a different app (no existence leak).
|
|
46
57
|
*/
|
|
47
58
|
readonly authorizeAppAccess?: OpsBlueprintAppAuthorizer;
|
|
59
|
+
/**
|
|
60
|
+
* The cache registry the writers mirror into (ggui#1541): the SAME one
|
|
61
|
+
* `ggui_ops_register_blueprint` and `ggui_ops_generate_blueprint` are
|
|
62
|
+
* given. When bound, a delete removes the blueprint's cache row (its
|
|
63
|
+
* vector and its exact-key binding) so the handshake stops reusing it.
|
|
64
|
+
*/
|
|
65
|
+
readonly cacheRegistry?: Pick<BlueprintRegistryDeps, 'vectorStore' | 'index'>;
|
|
48
66
|
}
|
|
49
67
|
export declare function createGguiOpsDeleteBlueprintHandler(deps: GguiOpsDeleteBlueprintDeps): import("../types.js").SharedHandler<{
|
|
50
68
|
appId: z.ZodOptional<z.ZodString>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/delete.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/delete.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAmB,KAAK,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAE/F,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAOxF;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;IACxD;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC;CAC/E;AAED,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,0BAA0B;;;;;;;GA8CjC"}
|
|
@@ -18,12 +18,23 @@
|
|
|
18
18
|
* a foreign `appId` input the authorizer denies surfaces the denial
|
|
19
19
|
* error before the row lookup ever runs.
|
|
20
20
|
*
|
|
21
|
+
* ## Out of reuse (ggui#1541)
|
|
22
|
+
*
|
|
23
|
+
* `ggui_ops_register_blueprint` and `ggui_ops_generate_blueprint` write a
|
|
24
|
+
* blueprint twice: the durable row, and a mirror in the cache registry, the
|
|
25
|
+
* store the handshake's exact-key probe matches from. So a delete removes
|
|
26
|
+
* both, the cache row first: a cache delete that fails fails the call
|
|
27
|
+
* before the durable row goes, and a retry completes it. An id whose
|
|
28
|
+
* durable row is already gone still has its cache row cleared in the
|
|
29
|
+
* caller's own app scope, which heals a row an earlier delete left behind.
|
|
30
|
+
*
|
|
21
31
|
* ## Audience
|
|
22
32
|
*
|
|
23
33
|
* `['ops']` — served on `/control`. NOT visible to agents on `/mcp`.
|
|
24
34
|
*/
|
|
25
35
|
import { z } from 'zod';
|
|
26
36
|
import { opsDeleteBlueprintInputSchema, } from '@ggui-ai/protocol';
|
|
37
|
+
import { deleteBlueprint } from '../renders/blueprint-registry.js';
|
|
27
38
|
import { defineHandler } from '../types.js';
|
|
28
39
|
import { resolveEffectiveAppId } from './app-access.js';
|
|
29
40
|
const opsInputSchema = opsDeleteBlueprintInputSchema.shape;
|
|
@@ -35,7 +46,7 @@ export function createGguiOpsDeleteBlueprintHandler(deps) {
|
|
|
35
46
|
name: 'ggui_ops_delete_blueprint',
|
|
36
47
|
title: 'Delete blueprint',
|
|
37
48
|
audience: ['ops'],
|
|
38
|
-
description: "Remove a blueprint row
|
|
49
|
+
description: "Remove a blueprint by id: its durable row, and its entry in the cache the handshake reuses blueprints from, so it is no longer reused. Idempotent — a second delete for the same id returns `{deleted: true}` without throwing. Cross-app probes return the same shape (no existence leak across apps). Mirrors `BlueprintStore.delete`'s no-throw contract. App-scoped variant curation for an app you operate — distinct from the personal saved-blueprint library (the _my_ tools).",
|
|
39
50
|
inputSchema: opsInputSchema,
|
|
40
51
|
outputSchema: opsOutputSchema,
|
|
41
52
|
async handler(rawInput, ctx) {
|
|
@@ -48,7 +59,11 @@ export function createGguiOpsDeleteBlueprintHandler(deps) {
|
|
|
48
59
|
});
|
|
49
60
|
const existing = await deps.blueprintStore.get(parsed.blueprintId);
|
|
50
61
|
if (existing === null) {
|
|
51
|
-
// Unknown id — idempotent.
|
|
62
|
+
// Unknown id — idempotent. Its cache row may outlive it (an earlier
|
|
63
|
+
// delete removed the durable row only): clear it in the caller's
|
|
64
|
+
// own app scope, which says nothing about any other app.
|
|
65
|
+
if (deps.cacheRegistry)
|
|
66
|
+
await deleteBlueprint(deps.cacheRegistry, appId, parsed.blueprintId);
|
|
52
67
|
return { deleted: true };
|
|
53
68
|
}
|
|
54
69
|
if (existing.appId !== appId) {
|
|
@@ -58,6 +73,10 @@ export function createGguiOpsDeleteBlueprintHandler(deps) {
|
|
|
58
73
|
// leak across app boundaries.
|
|
59
74
|
return { deleted: true };
|
|
60
75
|
}
|
|
76
|
+
// Out of reuse first, then the durable row: a cache delete that fails
|
|
77
|
+
// fails the call with the durable row intact, so a retry completes it.
|
|
78
|
+
if (deps.cacheRegistry)
|
|
79
|
+
await deleteBlueprint(deps.cacheRegistry, appId, parsed.blueprintId);
|
|
61
80
|
await deps.blueprintStore.delete(parsed.blueprintId);
|
|
62
81
|
return { deleted: true };
|
|
63
82
|
},
|
|
@@ -57,6 +57,17 @@ export declare class DirectionScopeWithoutDigestError extends Error {
|
|
|
57
57
|
readonly code: "direction_scope_without_digest";
|
|
58
58
|
constructor();
|
|
59
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* ggui#1570 — a registration named a parent (`clonedFrom`) this registration
|
|
62
|
+
* cannot record: an empty id, the row's own id, or an id that is not a row of
|
|
63
|
+
* the registering app in the durable store. One answer for all of them, and
|
|
64
|
+
* the same text for a missing row and another app's, so the refusal says
|
|
65
|
+
* nothing about another app's rows. Refused before anything is persisted.
|
|
66
|
+
*/
|
|
67
|
+
export declare class ClonedFromRefusedError extends Error {
|
|
68
|
+
readonly code: "cloned_from_refused";
|
|
69
|
+
constructor(clonedFrom: string);
|
|
70
|
+
}
|
|
60
71
|
export declare class MissingCredentialsError extends Error {
|
|
61
72
|
readonly code: "missing_credentials";
|
|
62
73
|
constructor(message?: string);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,MAAM,EAAE;CAM7D;AAED;;;;;;;;;;GAUG;AACH;;;;;;;GAOG;AACH,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,EAAG,gCAAgC,CAAU;;CAO3D;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,OAAO,CAAC,EAAE,MAAM;CAO7B;AAED;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,EAAG,mBAAmB,CAAU;IAC7C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;gBACZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAK5C"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,MAAM,EAAE;CAM7D;AAED;;;;;;;;;;GAUG;AACH;;;;;;;GAOG;AACH,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,EAAG,gCAAgC,CAAU;;CAO3D;AAED;;;;;;GAMG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,UAAU,EAAE,MAAM;CAM/B;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,OAAO,CAAC,EAAE,MAAM;CAO7B;AAED;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,EAAG,mBAAmB,CAAU;IAC7C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;gBACZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAK5C"}
|
|
@@ -63,6 +63,20 @@ export class DirectionScopeWithoutDigestError extends Error {
|
|
|
63
63
|
this.name = "DirectionScopeWithoutDigestError";
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* ggui#1570 — a registration named a parent (`clonedFrom`) this registration
|
|
68
|
+
* cannot record: an empty id, the row's own id, or an id that is not a row of
|
|
69
|
+
* the registering app in the durable store. One answer for all of them, and
|
|
70
|
+
* the same text for a missing row and another app's, so the refusal says
|
|
71
|
+
* nothing about another app's rows. Refused before anything is persisted.
|
|
72
|
+
*/
|
|
73
|
+
export class ClonedFromRefusedError extends Error {
|
|
74
|
+
code = "cloned_from_refused";
|
|
75
|
+
constructor(clonedFrom) {
|
|
76
|
+
super(`cloned_from_refused: clonedFrom "${clonedFrom}" is not another row of this app — a copy names a row of its own app, other than itself, that the store holds.`);
|
|
77
|
+
this.name = "ClonedFromRefusedError";
|
|
78
|
+
}
|
|
79
|
+
}
|
|
66
80
|
export class MissingCredentialsError extends Error {
|
|
67
81
|
code = "missing_credentials";
|
|
68
82
|
constructor(message) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Operator UX entry point. Dispatches through the bound
|
|
5
5
|
* {@link GeneratorRegistry} to mint a blueprint variant with
|
|
6
|
-
* operator-authored variance tags + optional default
|
|
6
|
+
* operator-authored variance tags + an optional operator-default mark.
|
|
7
7
|
*
|
|
8
8
|
* ## Behavior
|
|
9
9
|
*
|
|
@@ -177,7 +177,6 @@ export declare function createGguiOpsGenerateBlueprintHandler(deps: GguiOpsGener
|
|
|
177
177
|
}, {
|
|
178
178
|
blueprintId: z.ZodString;
|
|
179
179
|
codeHash: z.ZodOptional<z.ZodString>;
|
|
180
|
-
validatorScore: z.ZodOptional<z.ZodNumber>;
|
|
181
180
|
source: z.ZodObject<{
|
|
182
181
|
kind: z.ZodLiteral<"llm">;
|
|
183
182
|
generator: z.ZodString;
|
|
@@ -187,6 +186,5 @@ export declare function createGguiOpsGenerateBlueprintHandler(deps: GguiOpsGener
|
|
|
187
186
|
blueprintId: string;
|
|
188
187
|
source: import("@ggui-ai/protocol").LlmBlueprintSource;
|
|
189
188
|
codeHash?: string | undefined;
|
|
190
|
-
validatorScore?: number | undefined;
|
|
191
189
|
}>;
|
|
192
190
|
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,aAAa,EAGd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,YAAY,EAIlB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,aAAa,EAGd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,YAAY,EAIlB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAqBxF;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;;;;;;;OAOG;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;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,CACnB,GAAG,EAAE,cAAc,KAChB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,GAAG,qBAAqB,GAAG,IAAI,CAAC;IAC1E;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAC/B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,qBAAqB,CAAC;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC;IACxC;;;;;;;OAOG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CACzD;AA0BD,wBAAgB,qCAAqC,CACnD,IAAI,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;;;;GAkTnC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Operator UX entry point. Dispatches through the bound
|
|
5
5
|
* {@link GeneratorRegistry} to mint a blueprint variant with
|
|
6
|
-
* operator-authored variance tags + optional default
|
|
6
|
+
* operator-authored variance tags + an optional operator-default mark.
|
|
7
7
|
*
|
|
8
8
|
* ## Behavior
|
|
9
9
|
*
|
|
@@ -52,7 +52,8 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
52
52
|
import { z } from "zod";
|
|
53
53
|
import { assertContractNoRetiredFields } from "../renders/assert-contract-no-retired-fields.js";
|
|
54
54
|
import { assertGadgetsRegistered } from "../renders/assert-gadgets.js";
|
|
55
|
-
import {
|
|
55
|
+
import { admitGeneratorBuild, } from "../renders/index.js";
|
|
56
|
+
import { mirrorIntoCache } from "./cache-mirror.js";
|
|
56
57
|
import { defineHandler } from "../types.js";
|
|
57
58
|
import { resolveEffectiveAppId } from "./app-access.js";
|
|
58
59
|
import { GenerationFailedError, GeneratorNotFoundError, MissingCredentialsError, } from "./errors.js";
|
|
@@ -61,7 +62,6 @@ const opsInputSchema = opsGenerateBlueprintInputSchema.shape;
|
|
|
61
62
|
const opsOutputSchema = z.object({
|
|
62
63
|
blueprintId: z.string().min(1),
|
|
63
64
|
codeHash: z.string().optional(),
|
|
64
|
-
validatorScore: z.number().min(0).max(1).optional(),
|
|
65
65
|
source: z
|
|
66
66
|
.object({
|
|
67
67
|
kind: z.literal("llm"),
|
|
@@ -70,26 +70,6 @@ const opsOutputSchema = z.object({
|
|
|
70
70
|
})
|
|
71
71
|
.strict(),
|
|
72
72
|
}).shape;
|
|
73
|
-
/**
|
|
74
|
-
* Read the optional `validatorScore` carried on
|
|
75
|
-
* {@link GenerationMetadata} by the advanced generator, which does
|
|
76
|
-
* not yet have an explicit field on the canonical interface. Until
|
|
77
|
-
* that lands the score arrives as a structural pass-through on
|
|
78
|
-
* `metadata` — the read is type-guarded here so the cast is
|
|
79
|
-
* confined to one place and the call sites stay clean.
|
|
80
|
-
*/
|
|
81
|
-
function readValidatorScore(metadata) {
|
|
82
|
-
if (!metadata || typeof metadata !== "object")
|
|
83
|
-
return undefined;
|
|
84
|
-
const candidate = metadata.validatorScore;
|
|
85
|
-
if (typeof candidate !== "number")
|
|
86
|
-
return undefined;
|
|
87
|
-
if (!Number.isFinite(candidate))
|
|
88
|
-
return undefined;
|
|
89
|
-
if (candidate < 0 || candidate > 1)
|
|
90
|
-
return undefined;
|
|
91
|
-
return candidate;
|
|
92
|
-
}
|
|
93
73
|
/**
|
|
94
74
|
* Resolve which generator to dispatch. Throws {@link GeneratorNotFoundError}
|
|
95
75
|
* with a clear "did you mean…" payload when the slug is unknown.
|
|
@@ -117,7 +97,7 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
|
|
|
117
97
|
name: "ggui_ops_generate_blueprint",
|
|
118
98
|
title: "Generate blueprint",
|
|
119
99
|
audience: ["ops"],
|
|
120
|
-
description: "Author a new blueprint variant for the target app (the caller's bound app by default, or an explicitly named app the deployment's authorization policy accepts). Dispatches through the registry's selected generator (defaults to `registry.defaultGenerator()` when the slug is omitted) and persists the resulting code body + metadata against a fresh `blueprintId`. Optionally
|
|
100
|
+
description: "Author a new blueprint variant for the target app (the caller's bound app by default, or an explicitly named app the deployment's authorization policy accepts). Dispatches through the registry's selected generator (defaults to `registry.defaultGenerator()` when the slug is omitted) and persists the resulting code body + metadata against a fresh `blueprintId`. Optionally marks the new blueprint as the operator default for its `(appId, contractHash)` group (the mark orders blueprint listings; it does not decide which blueprint serves a render). Persona tags are normalized (lowercase + trim); near-duplicates surface a warning via telemetry. Returns the new id + content-hash + validator score + the stamped provenance (`source`, llm arm: engine generator slug + model, from the engine's own metadata stamp) — code body lives in the bound store, fetched via render's fast-path on cache hit. App-scoped variant curation for an app you operate — distinct from the personal saved-blueprint library (the _my_ tools).",
|
|
121
101
|
inputSchema: opsInputSchema,
|
|
122
102
|
outputSchema: opsOutputSchema,
|
|
123
103
|
async handler(rawInput, ctx) {
|
|
@@ -255,12 +235,6 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
|
|
|
255
235
|
// bytes. A 32-hex prefix here (ggui#1287) was refused by every
|
|
256
236
|
// conforming code store.
|
|
257
237
|
const codeHash = createHash("sha256").update(componentCode).digest("hex");
|
|
258
|
-
// The advanced generator tunnels `validatorScore` through
|
|
259
|
-
// `metadata` until the UiGenerator interface widens to carry
|
|
260
|
-
// it explicitly. Read it via the typed helper so the default
|
|
261
|
-
// generator (which never sets it) and the advanced generator
|
|
262
|
-
// (which does) both round-trip cleanly.
|
|
263
|
-
const validatorScore = readValidatorScore(result.metadata);
|
|
264
238
|
// Engine-GENERATED code: provenance is the llm arm, stamped from
|
|
265
239
|
// the engine's own metadata claim — the SAME values the cache-
|
|
266
240
|
// registry mirror below records, so the two stores can never
|
|
@@ -270,6 +244,13 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
|
|
|
270
244
|
generator: result.metadata.generator,
|
|
271
245
|
model: result.metadata.model,
|
|
272
246
|
};
|
|
247
|
+
// ggui#1280 — the minting engine's build, through the registry's one
|
|
248
|
+
// admission rule. The durable row below carries it. The cache mirror's
|
|
249
|
+
// registration receives the same value: it rides that registry's
|
|
250
|
+
// vector-store row (ggui#1476) and, when the mirror writes through to a
|
|
251
|
+
// separate durable store, the row it writes there under this same id
|
|
252
|
+
// (ggui#1497, see `mirrorIntoCache`).
|
|
253
|
+
const build = admitGeneratorBuild(source, result.metadata.build);
|
|
273
254
|
const blueprintId = mintBlueprintId();
|
|
274
255
|
const blueprint = {
|
|
275
256
|
blueprintId,
|
|
@@ -286,7 +267,7 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
|
|
|
286
267
|
createdAt: now(),
|
|
287
268
|
createdBy: "operator",
|
|
288
269
|
contract,
|
|
289
|
-
...(
|
|
270
|
+
...(build !== undefined ? { build } : {}),
|
|
290
271
|
};
|
|
291
272
|
await deps.blueprintStore.put(blueprint);
|
|
292
273
|
if (deps.putCode) {
|
|
@@ -305,31 +286,40 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
|
|
|
305
286
|
parsed.seedPrompt ??
|
|
306
287
|
normalizedPersona ??
|
|
307
288
|
`operator-authored blueprint (${blueprintId})`;
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
289
|
+
// ggui#1497 — ONE id per generation: the cache row serves the
|
|
290
|
+
// durable row's id (see `mirrorIntoCache` for what else it writes).
|
|
291
|
+
await mirrorIntoCache({
|
|
292
|
+
cacheRegistry: deps.cacheRegistry,
|
|
293
|
+
writerStore: deps.blueprintStore,
|
|
294
|
+
appId,
|
|
295
|
+
blueprintId,
|
|
296
|
+
input: {
|
|
297
|
+
kind: "template",
|
|
298
|
+
contract,
|
|
299
|
+
intent: intentForCache,
|
|
300
|
+
// ggui#1275 — an explicit intent or a seed prompt states the
|
|
301
|
+
// UI's task; a persona or the placeholder is a stand-in the
|
|
302
|
+
// matcher's judge never sees.
|
|
303
|
+
intentSource: parsed.intent !== undefined || parsed.seedPrompt !== undefined
|
|
304
|
+
? "authored"
|
|
305
|
+
: "fallback",
|
|
306
|
+
componentCode,
|
|
307
|
+
// The cache row MUST carry the same variance as the MVB
|
|
308
|
+
// row: `registerBlueprint` keys the exact-lookup on
|
|
309
|
+
// `variantKey(variance)`, so omitting it here filed every
|
|
310
|
+
// operator-authored variant under the default-variant
|
|
311
|
+
// sentinel — invisible to any request that asks for the
|
|
312
|
+
// persona it was minted for.
|
|
313
|
+
variance: blueprint.variance,
|
|
314
|
+
// Operator-DISPATCHED but engine-GENERATED: the code came
|
|
315
|
+
// out of `generator.generate(...)`, so provenance is the
|
|
316
|
+
// llm arm — the same `source` stamped on the MVB row above.
|
|
317
|
+
// The two axes disagree here on purpose, which is exactly
|
|
318
|
+
// why `createdBy` cannot be derived from `source`.
|
|
319
|
+
source,
|
|
320
|
+
...(build !== undefined ? { build } : {}),
|
|
321
|
+
createdBy: "operator",
|
|
322
|
+
},
|
|
333
323
|
});
|
|
334
324
|
}
|
|
335
325
|
catch (err) {
|
|
@@ -352,7 +342,7 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
|
|
|
352
342
|
}
|
|
353
343
|
}
|
|
354
344
|
}
|
|
355
|
-
// 7.
|
|
345
|
+
// 7. Mark as operator default when requested.
|
|
356
346
|
if (parsed.setAsOperatorDefault === true) {
|
|
357
347
|
await deps.blueprintStore.setOperatorDefault(blueprintId);
|
|
358
348
|
}
|
|
@@ -381,7 +371,6 @@ export function createGguiOpsGenerateBlueprintHandler(deps) {
|
|
|
381
371
|
blueprintId,
|
|
382
372
|
codeHash,
|
|
383
373
|
source,
|
|
384
|
-
...(validatorScore !== undefined ? { validatorScore } : {}),
|
|
385
374
|
};
|
|
386
375
|
return output;
|
|
387
376
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAQxF;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C;;;;;;;OAOG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CACzD;
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/ops-blueprint/list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAyB,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAQxF;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C;;;;;;;OAOG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CACzD;AAkBD,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,yBAAyB;;;;;;;;;;GAyFhC"}
|
|
@@ -42,8 +42,7 @@ const opsOutputSchema = {
|
|
|
42
42
|
};
|
|
43
43
|
/**
|
|
44
44
|
* Sort blueprints by `createdAt desc`, then `blueprintId asc` as
|
|
45
|
-
* stable tiebreaker.
|
|
46
|
-
* ladder ordering (see `@ggui-ai/mcp-server-core/blueprint-selector`).
|
|
45
|
+
* stable tiebreaker.
|
|
47
46
|
*/
|
|
48
47
|
function sortBlueprintsByCreatedAtDesc(rows) {
|
|
49
48
|
return [...rows].sort((a, b) => {
|