feat(spec): 蓝图可以声明汇总字段(含带条件的汇总) - #4425
Merged
Merged
Conversation
…onditional one
`BlueprintFieldSchema` had no slot for `summaryOperations`, so a `summary`
field could only ever be proposed as a bare shell. Two consequences, both
observed live (cloud#970):
1. `z.object` STRIPS unknown keys, so a blueprint that correctly declared
`{ type:'summary', summaryOperations:{ object:'task', function:'count',
filter:{ status:'completed' } } }` silently lost that config at the parse
waist and materialized runtime-dead.
2. The strict structured-output mirror could not express it either, so the
design step — the one place the aggregation is actually known ("已完成任务数
counts only completed tasks") — had nowhere to put it.
This matters beyond tidiness: the engine recomputes roll-ups only when a CHILD
row is written, so a `summaryOperations` bolted on AFTER a build's sample data
loaded leaves the parent values empty until someone edits a child. The design
phase is the only place it can be declared in time.
Adds `BlueprintSummaryOperationsSchema` (object / function / field /
relationshipField, plus the predicate) to both the lenient schema and the strict
mirror. Strict mode cannot represent the canonical `filter` map (open-ended
`additionalProperties`), so the predicate is a flat `conditions` array of
`{field, op, value}` — the same shape a dashboard widget's `condition` already
uses; the lenient schema also accepts a real `filter` map for a hand-authored
blueprint. `BlueprintWidgetConditionSchema` becomes an alias of the now-shared
`BlueprintConditionSchema`.
Also makes the lenient schema's top-level `summary` OPTIONAL. It is a purely
descriptive one-liner with no structural role, but `apply_blueprint` parses the
model's re-emitted blueprint against this schema — so omitting it rejected the
whole build with `path: "summary"`, which the model read as "the summary FIELDS
are invalid" and repaired by DELETING the roll-up fields. The strict design
contract still requires it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 107 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…+ changeset Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
59 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
BlueprintFieldSchema没有承载summaryOperations的位置,于是蓝图里的summary字段只能是个空壳。实测(cloud#970)造成两处后果:z.object会丢弃未知键。模型其实写对了 ——{ type:'summary', summaryOperations:{ object:'task', function:'count', filter:{ status:'completed' } } }—— 但这份配置在 parse 这道关口被静默剥掉,落库即 runtime-dead。SolutionBlueprintStrictSchema)同样表达不了它,所以方案设计阶段(唯一真正知道聚合语义的地方,"已完成任务数只统计 completed")无处安放这个信息。这不只是整洁问题:引擎只在子记录写入时重算 roll-up。等蓝图把示例数据灌完之后再补
summaryOperations,父记录上的值会一直是空的,直到有人去改一条子记录。所以它必须能在设计阶段就声明。改动
BlueprintSummaryOperationsSchema(object/function/field/relationshipField+ 谓词),挂到BlueprintFieldSchema.summaryOperations,宽松版与严格镜像都有。filter这种开放键的 map(additionalProperties),所以谓词用扁平的conditions: [{field, op, value}]数组 —— 与 dashboard widget 的condition完全同形(既有先例);宽松版同时接受真正的filtermap,供手写蓝图使用。BlueprintWidgetConditionSchema改为共享的BlueprintConditionSchema的别名。summary在宽松 schema 中改为可选。它是纯描述性的一句话、没有任何结构作用,但apply_blueprint用这份 schema 校验模型回传的蓝图 —— 缺了它整份蓝图被拒,报错path: "summary",而模型把这条读成了"summary 字段有问题",于是把两个汇总字段删掉当作修复。严格设计契约仍然要求它。测试
packages/spec全量 285 files / 7228 tests 通过;新增用例覆盖:宽松 schema 保留summaryOperations(含filter与conditions两种写法)、缺summary不再被拒(缺objects仍然被拒)、严格镜像携带summaryOperations且conditions为扁平数组。消费侧(cloud
service-ai-studio的apply_blueprint物化 + graph-lint)在 objectstack-ai/cloud#970 的 PR 中一并落地。🤖 Generated with Claude Code