@agent-native/core 0.176.0-nightly-20260828040116 → 0.176.1
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/corpus/README.md +1 -1
- package/corpus/templates/analytics/CHANGELOG.md +15 -0
- package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +19 -18
- package/corpus/templates/analytics/docs/schemas/tracked-events.md +5 -1
- package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +8 -6
- package/corpus/templates/assets/.agents/skills/assets-navigation/SKILL.md +9 -6
- package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +22 -21
- package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +1 -1
- package/corpus/templates/assets/.agents/skills/logo-composite/SKILL.md +11 -9
- package/corpus/templates/assets/AGENTS.md +16 -11
- package/corpus/templates/assets/CHANGELOG.md +6 -0
- package/corpus/templates/assets/actions/_helpers.ts +15 -0
- package/corpus/templates/assets/actions/_template-access.ts +71 -0
- package/corpus/templates/assets/actions/_template-input.ts +51 -0
- package/corpus/templates/assets/actions/associate-template.ts +39 -0
- package/corpus/templates/assets/actions/create-generation-preset.ts +3 -68
- package/corpus/templates/assets/actions/create-generation-session.ts +7 -10
- package/corpus/templates/assets/actions/create-library-from-preset.ts +2 -2
- package/corpus/templates/assets/actions/create-library.ts +2 -2
- package/corpus/templates/assets/actions/create-template.ts +86 -0
- package/corpus/templates/assets/actions/delete-generation-preset.ts +3 -29
- package/corpus/templates/assets/actions/delete-library.ts +11 -2
- package/corpus/templates/assets/actions/delete-template.ts +36 -0
- package/corpus/templates/assets/actions/duplicate-library.ts +9 -5
- package/corpus/templates/assets/actions/duplicate-template.ts +81 -0
- package/corpus/templates/assets/actions/generate-asset.ts +6 -3
- package/corpus/templates/assets/actions/generate-image-batch.ts +6 -5
- package/corpus/templates/assets/actions/generate-image.ts +23 -18
- package/corpus/templates/assets/actions/get-generation-session.ts +14 -5
- package/corpus/templates/assets/actions/get-template.ts +25 -0
- package/corpus/templates/assets/actions/list-generation-presets.ts +8 -26
- package/corpus/templates/assets/actions/list-templates.ts +90 -0
- package/corpus/templates/assets/actions/merge-duplicate-templates.ts +178 -0
- package/corpus/templates/assets/actions/navigate.ts +4 -1
- package/corpus/templates/assets/actions/rerun-generation-run.ts +3 -5
- package/corpus/templates/assets/actions/update-generation-preset.ts +4 -88
- package/corpus/templates/assets/actions/update-template.ts +87 -0
- package/corpus/templates/assets/actions/view-screen.ts +10 -0
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +6 -1
- package/corpus/templates/assets/app/components/library/CreateTemplateDialog.tsx +214 -0
- package/corpus/templates/assets/app/components/library/TemplatesPanel.tsx +116 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +11 -2
- package/corpus/templates/assets/app/i18n-data.ts +393 -0
- package/corpus/templates/assets/app/lib/asset-urls.ts +34 -0
- package/corpus/templates/assets/app/lib/picker-chat-handoff.ts +9 -5
- package/corpus/templates/assets/app/lib/template-composer-reference.ts +62 -0
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +2 -2
- package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +7 -2431
- package/corpus/templates/assets/app/routes/brand-kits.$id_.settings.tsx +4 -7
- package/corpus/templates/assets/app/routes/library.tsx +15 -31
- package/corpus/templates/assets/app/routes/templates.$templateId.tsx +2492 -0
- package/corpus/templates/assets/app/routes/templates._index.tsx +360 -0
- package/corpus/templates/assets/app/routes/templates.tsx +11 -0
- package/corpus/templates/assets/changelog/2026-08-26-templates-across-brand-kits.md +5 -0
- package/corpus/templates/assets/server/db/index.ts +10 -0
- package/corpus/templates/assets/server/db/schema.ts +25 -0
- package/corpus/templates/assets/server/lib/generation-presets.ts +94 -32
- package/corpus/templates/assets/server/lib/{preset-chat-context.ts → template-chat-context.ts} +48 -34
- package/corpus/templates/assets/server/plugins/agent-chat.ts +72 -64
- package/corpus/templates/assets/server/plugins/creative-context.ts +0 -2
- package/corpus/templates/assets/server/plugins/db.ts +87 -0
- package/corpus/templates/assets/shared/api.ts +12 -0
- package/corpus/templates/chat/CHANGELOG.md +11 -0
- package/corpus/templates/clips/app/components/library/search-bar.tsx +7 -1
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +1 -1
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +262 -6
- package/corpus/templates/design/CHANGELOG.md +28 -0
- package/corpus/templates/design/actions/update-file.ts +4 -6
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +5 -2
- package/corpus/templates/design/app/components/design/EditPanel.tsx +8 -0
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +397 -12
- package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +15 -0
- package/corpus/templates/design/app/components/design/edit-panel/style-change-types.ts +14 -0
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +352 -111
- package/corpus/templates/design/app/components/design/inspector/design-icons.tsx +1 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +85 -5
- package/corpus/templates/design/app/pages/design-editor/commands/apply-layout-flow.ts +78 -0
- package/corpus/templates/design/app/pages/design-editor/commands/pasted-image-files.ts +110 -14
- package/corpus/templates/design/changelog/2026-08-27-grid-auto-layout-now-lays-children-out-in-cells-and-shows-the-cell-grid.md +6 -0
- package/corpus/templates/design/changelog/2026-08-27-outermost-frames-now-show-their-name-on-the-canvas.md +6 -0
- package/corpus/templates/design/server/source-workspace.ts +1 -7
- package/corpus/templates/design/shared/code-layer.ts +46 -10
- package/corpus/templates/design/shared/locked-layers.ts +178 -64
- package/corpus/templates/factory/AGENTS.md +2 -1
- package/corpus/templates/factory/actions/govern-agent-native-pull-request.ts +757 -42
- package/corpus/templates/factory/actions/ingest-github-observation.ts +10 -1
- package/corpus/templates/factory/actions/reconcile-triage-run.ts +3 -0
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +10 -1
- package/corpus/templates/factory/server/triage/ai-services-git.ts +6 -0
- package/corpus/templates/factory/server/triage/contracts.ts +1 -0
- package/corpus/templates/factory/server/triage/github-client.ts +93 -15
- package/corpus/templates/factory/server/triage/pr-monitor.ts +3 -0
- package/corpus/templates/factory/server/triage/pr-policy.ts +243 -31
- package/corpus/templates/factory/server/triage/review-skill-alignment.ts +16 -4
- package/corpus/templates/slides/CHANGELOG.md +15 -0
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +7 -2
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +37 -1
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +941 -219
- package/corpus/templates/slides/app/components/editor/SlidesLayersPanel.tsx +209 -0
- package/corpus/templates/slides/app/components/editor/slide-object-interactions.ts +194 -4
- package/corpus/templates/slides/app/components/editor/slide-style.ts +36 -0
- package/corpus/templates/slides/app/context/DeckContext.tsx +2 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
- package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +26 -8
- package/corpus/templates/slides/app/lib/slide-image-replacement.ts +83 -2
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +213 -51
- package/corpus/templates/slides/app/root.tsx +25 -6
- package/dist/observability/routes.d.ts +3 -3
- package/dist/observability/traces.d.ts +8 -0
- package/dist/observability/traces.js +27 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/templates/chat/CHANGELOG.md +11 -0
- package/package.json +3 -3
- package/src/templates/chat/CHANGELOG.md +11 -0
- package/corpus/templates/assets/app/components/library/GenerationPresetsPanel.tsx +0 -326
package/corpus/README.md
CHANGED
|
@@ -3,6 +3,21 @@
|
|
|
3
3
|
All notable user-facing changes to Agent-Native Analytics are documented here. Open it any
|
|
4
4
|
time from the command menu (Cmd+K → "What's new") or from Settings.
|
|
5
5
|
|
|
6
|
+
## 2026-08-27
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Dashboard owners can archive dashboards from the actions menu.
|
|
11
|
+
- See signup, onboarding, activation, and sharing drop-off in one filterable dashboard.
|
|
12
|
+
|
|
13
|
+
### Improved
|
|
14
|
+
|
|
15
|
+
- Show connected Google names and profile photos in analytics
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Analytics exports now show a direct download in chat and reject failed responses
|
|
20
|
+
|
|
6
21
|
## 2026-08-26
|
|
7
22
|
|
|
8
23
|
### Improved
|
|
@@ -117,24 +117,25 @@ event_name = '$ai_sentiment'
|
|
|
117
117
|
|
|
118
118
|
Useful query fields live in `properties`:
|
|
119
119
|
|
|
120
|
-
| Property | Description
|
|
121
|
-
| ------------------------------------------------ |
|
|
122
|
-
| `$ai_trace_id`, `run_id` | Agent run id
|
|
123
|
-
| `$ai_session_id`, `thread_id` | Chat/thread id, when available
|
|
124
|
-
| `$ai_model`, `model` | Model used
|
|
125
|
-
| `$ai_provider`, `provider` | Engine/provider name
|
|
126
|
-
| `$ai_input_tokens`, `input_tokens` | Input tokens
|
|
127
|
-
| `$ai_output_tokens`, `output_tokens` | Output tokens
|
|
128
|
-
| `cache_read_tokens`, `cache_write_tokens` | Prompt-cache token counts
|
|
129
|
-
| `$ai_total_cost_usd`, `cost_usd` | Estimated run cost in USD
|
|
130
|
-
| `cost_cents_x100` | Estimated run cost in centicents
|
|
131
|
-
| `duration_ms` | Run duration in milliseconds
|
|
132
|
-
| `$ai_latency` | Model time in seconds (run duration minus tool time), on `$ai_generation`
|
|
133
|
-
| `tool_calls`, `successful_tools`, `failed_tools` | Complete tool-call counts
|
|
134
|
-
| `tools`, `tools_truncated` | First 50 tool names, offsets, durations, statuses, and error classes, including interrupted calls
|
|
135
|
-
| `delegated`, `delegation_protocol`, `caller_app` | Delegated-run attribution
|
|
136
|
-
| `a2a_task_id`, `parent_run_id`, `parent_turn_id` | Cross-app trace linkage, when available
|
|
137
|
-
| `$ai_is_error`, `status`, `$ai_error` | Error status and message, when applicable
|
|
120
|
+
| Property | Description |
|
|
121
|
+
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
|
122
|
+
| `$ai_trace_id`, `run_id` | Agent run id |
|
|
123
|
+
| `$ai_session_id`, `thread_id` | Chat/thread id, when available |
|
|
124
|
+
| `$ai_model`, `model` | Model used |
|
|
125
|
+
| `$ai_provider`, `provider` | Engine/provider name |
|
|
126
|
+
| `$ai_input_tokens`, `input_tokens` | Input tokens |
|
|
127
|
+
| `$ai_output_tokens`, `output_tokens` | Output tokens |
|
|
128
|
+
| `cache_read_tokens`, `cache_write_tokens` | Prompt-cache token counts |
|
|
129
|
+
| `$ai_total_cost_usd`, `cost_usd` | Estimated run cost in USD |
|
|
130
|
+
| `cost_cents_x100` | Estimated run cost in centicents |
|
|
131
|
+
| `duration_ms` | Run duration in milliseconds |
|
|
132
|
+
| `$ai_latency` | Model time in seconds (run duration minus tool time), on `$ai_generation` |
|
|
133
|
+
| `tool_calls`, `successful_tools`, `failed_tools` | Complete tool-call counts |
|
|
134
|
+
| `tools`, `tools_truncated` | First 50 tool names, offsets, durations, statuses, and error classes, including interrupted calls |
|
|
135
|
+
| `delegated`, `delegation_protocol`, `caller_app` | Delegated-run attribution |
|
|
136
|
+
| `a2a_task_id`, `parent_run_id`, `parent_turn_id` | Cross-app trace linkage, when available |
|
|
137
|
+
| `$ai_is_error`, `status`, `$ai_error` | Error status and message, when applicable |
|
|
138
|
+
| `$ai_http_status` | Provider HTTP status: 200 on a completed call, the reported status on a failed one, absent when the failure carried none |
|
|
138
139
|
|
|
139
140
|
The `tools` array never includes tool arguments, results, or error messages.
|
|
140
141
|
Use `tools_truncated` with the complete `tool_calls` count when a run exceeds
|
|
@@ -28,7 +28,11 @@ Events tracked by application instrumentation and stored in the configured appli
|
|
|
28
28
|
server-side tracking. Properties include `$ai_trace_id`, `$ai_session_id`,
|
|
29
29
|
`$ai_model`, `$ai_provider`, `$ai_input_tokens`, `$ai_output_tokens`,
|
|
30
30
|
`$ai_latency`, `$ai_total_cost_usd`, `run_id`, `thread_id`,
|
|
31
|
-
`cost_cents_x100`, `duration_ms`, `tool_calls`, `status`,
|
|
31
|
+
`cost_cents_x100`, `duration_ms`, `tool_calls`, `status`, `$ai_http_status`,
|
|
32
|
+
and error fields. `$ai_http_status` is 200 on a call that streamed to
|
|
33
|
+
completion and the provider's status on one that failed; it is absent when
|
|
34
|
+
the failure carried no status, so an unclassifiable transport drop is never
|
|
35
|
+
reported as a known rejection.
|
|
32
36
|
`$ai_latency` is model time in seconds; `duration_ms` is the full run in
|
|
33
37
|
milliseconds, and the two differ by the time spent in tools.
|
|
34
38
|
A bounded `tools` array records only tool names, relative start times,
|
|
@@ -50,13 +50,15 @@ claiming a brand match.
|
|
|
50
50
|
`generate-image-batch`, `generate-video`, `refresh-generation-run`, and
|
|
51
51
|
`export-asset`.
|
|
52
52
|
- In chat, consume composer `@` references as structured generation inputs:
|
|
53
|
-
`brand-kit` maps to `libraryId`, `
|
|
53
|
+
`brand-kit` maps to `libraryId`, `template` maps to `templateId`, and
|
|
54
54
|
`media-type` chooses image generation versus video generation. If no mention
|
|
55
55
|
is available, use `view-screen`, `list-libraries`, and
|
|
56
|
-
`list-
|
|
57
|
-
- Use
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
`list-templates` to choose explicit args.
|
|
57
|
+
- Use Templates when the user asks for a repeatable output format like social
|
|
58
|
+
image, blog hero, or diagram. Call `list-templates` and pass `templateId`
|
|
59
|
+
through generation/refinement actions. Templates may be global or associated
|
|
60
|
+
with one brand kit; only associated templates can pin images, skeletons, or
|
|
61
|
+
a canonical logo. `*-generation-preset` actions are deprecated aliases.
|
|
60
62
|
- Use generation sessions when another person needs to continue improving a
|
|
61
63
|
candidate. Sessions carry the brief, preset, active asset, feedback, and run
|
|
62
64
|
IDs without requiring the original chat thread.
|
|
@@ -90,7 +92,7 @@ claiming a brand match.
|
|
|
90
92
|
`generate-image-batch` returns, use its returned `images` / asset fields
|
|
91
93
|
directly; do not call `get-generation-run`, `refresh-generation-run`, or
|
|
92
94
|
regenerate just to verify image runs.
|
|
93
|
-
5. For
|
|
95
|
+
5. For template-backed work, pass a mentioned or selected `templateId`; for handoff
|
|
94
96
|
work, pass `sessionId`.
|
|
95
97
|
6. Let the server choose a small deterministic reference set unless the user
|
|
96
98
|
named exact assets. Canonical style anchors come from
|
|
@@ -26,12 +26,15 @@ generation, or embed target is unclear.
|
|
|
26
26
|
use the right agent sidebar only on non-Create routes with view-transition
|
|
27
27
|
handoff back to `/`.
|
|
28
28
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
- Humans
|
|
32
|
-
`/
|
|
33
|
-
`{ view: "
|
|
34
|
-
|
|
29
|
+
## Templates
|
|
30
|
+
|
|
31
|
+
- Humans browse Templates at `/templates` and edit one at
|
|
32
|
+
`/templates/:templateId`. Use `navigate` with `{ view: "templates" }` or
|
|
33
|
+
`{ view: "template", templateId }`. Legacy `{ view: "preset", libraryId,
|
|
34
|
+
presetId }` navigation still resolves for existing conversations.
|
|
35
|
+
- Global templates work with any accessible brand kit. Associated templates are
|
|
36
|
+
limited to their kit and are required for pinned images, skeletons, and logo
|
|
37
|
+
compositing. See `logo-composite` for the
|
|
35
38
|
`settings.skeletonSpec` shape and compositing behavior.
|
|
36
39
|
|
|
37
40
|
## Context tab
|
|
@@ -58,8 +58,8 @@ evidence, screenshots, or exact logos.
|
|
|
58
58
|
IDs/URLs; do not follow it with `get-generation-run`,
|
|
59
59
|
`refresh-generation-run`, or more generation unless the user asks for another
|
|
60
60
|
direction or the returned slot has `ok: false`.
|
|
61
|
-
- For repeatable deliverables, honor a `
|
|
62
|
-
`list-
|
|
61
|
+
- For repeatable deliverables, honor a `template` @mention as `templateId` or
|
|
62
|
+
call `list-templates` when choosing one. Pass the template through
|
|
63
63
|
`generate-image`, `generate-image-batch`, `refine-image`, or
|
|
64
64
|
`rerun-generation-run`.
|
|
65
65
|
- For designer handoff, preserve `sessionId` and call
|
|
@@ -77,40 +77,40 @@ evidence, screenshots, or exact logos.
|
|
|
77
77
|
`generate-image-batch` / `refine-image`. The design team uses the audit log
|
|
78
78
|
to review quality by app, library, model, prompt, and lineage.
|
|
79
79
|
|
|
80
|
-
## Composer Mentions And Tagged
|
|
80
|
+
## Composer Mentions And Tagged Templates
|
|
81
81
|
|
|
82
82
|
- Composer `@` mentions are the source of generation inputs. Map `brand-kit`
|
|
83
|
-
references to `libraryId`, `
|
|
83
|
+
references to `libraryId`, `template` references to `templateId`, and `media-type`
|
|
84
84
|
references to choosing image (`generate-image` / `generate-image-batch`) or
|
|
85
85
|
video (`generate-video`) generation.
|
|
86
86
|
- The current library view auto-tags its brand kit as a visible removable chip,
|
|
87
|
-
and the
|
|
87
|
+
and the template editor auto-tags an associated template with its brand kit.
|
|
88
88
|
- The image model is the only remaining composer-side default; the image-model
|
|
89
89
|
picker writes `imageGenerationModel`, which image generation actions may use
|
|
90
90
|
when `model` is omitted.
|
|
91
|
-
- When a `
|
|
91
|
+
- When a `template` is tagged, the server embeds that template's aesthetics and
|
|
92
92
|
creative philosophy (brand style brief, prompt template, text/logo policy,
|
|
93
|
-
output format) into your message inside a `<tagged-
|
|
93
|
+
output format) into your message inside a `<tagged-templates>` block.
|
|
94
94
|
Study and internalize that brief before you generate — let it drive
|
|
95
|
-
composition, mood, lighting, and subject — then pass the `
|
|
95
|
+
composition, mood, lighting, and subject — then pass the `templateId` to
|
|
96
96
|
`generate-image` / `generate-image-batch` so the saved format/model/tier/logo
|
|
97
97
|
apply automatically. Do not restate those as ad-hoc args.
|
|
98
98
|
|
|
99
|
-
##
|
|
99
|
+
## Template-first Generation
|
|
100
100
|
|
|
101
|
-
- Image requests without a tagged
|
|
102
|
-
|
|
101
|
+
- Image requests without a tagged template are template-first: the user may not know
|
|
102
|
+
templates exist. Compare the request against each template's title, description,
|
|
103
103
|
and category, and if one matches the use case (e.g. "livestream poster" -> a
|
|
104
|
-
Livestream Announcement
|
|
105
|
-
ad-hoc settings. Only generate
|
|
104
|
+
Livestream Announcement template), generate with its `templateId` instead of
|
|
105
|
+
ad-hoc settings. Only generate without a template when nothing plausibly matches.
|
|
106
106
|
- Before any ad-hoc generation for a brand kit, call
|
|
107
|
-
`list-
|
|
108
|
-
|
|
107
|
+
`list-templates` and scan titles/descriptions/categories for a use-case match.
|
|
108
|
+
A template encodes the designer's format, model, layout, and
|
|
109
109
|
reference board; using it is always better than improvising.
|
|
110
|
-
- If one
|
|
110
|
+
- If one template clearly matches: use its `templateId`; do not restate its saved
|
|
111
111
|
aspect ratio/size/model/tier. If several plausibly match: pick the best and
|
|
112
112
|
state which one you used; do not ask the user to choose.
|
|
113
|
-
- Match named people/products/backdrops in the request to the
|
|
113
|
+
- Match named people/products/backdrops in the request to the template's
|
|
114
114
|
reference board entry labels in `settings.presetReferences`. Fill required
|
|
115
115
|
variable entries via `presetReferenceFills`: search the library for assets of
|
|
116
116
|
those people first; ask the user for photos only when none exist. Never skip a
|
|
@@ -122,8 +122,9 @@ evidence, screenshots, or exact logos.
|
|
|
122
122
|
optional `textPlacement` to `generate-image` or each `generate-image-batch`
|
|
123
123
|
slot. Keep the general `prompt` for creative direction; the structured text
|
|
124
124
|
fields are what allow the pipeline to render copy instead of suppressing it.
|
|
125
|
-
- If nothing matches: generate ad-hoc, say that no
|
|
126
|
-
|
|
125
|
+
- If nothing matches: generate ad-hoc, say that no template fit, and mention a
|
|
126
|
+
template could be created for this recurring use case. The deprecated
|
|
127
|
+
`*-generation-preset` actions remain aliases for existing agent threads.
|
|
127
128
|
|
|
128
129
|
## Prompting
|
|
129
130
|
|
|
@@ -131,13 +132,13 @@ evidence, screenshots, or exact logos.
|
|
|
131
132
|
- Let the server choose references unless the user named exact assets. Automatic
|
|
132
133
|
generation uses up to 6 relevant current references, seeded by canonical
|
|
133
134
|
style anchors; explicit `referenceAssetIds` are preserved.
|
|
134
|
-
-
|
|
135
|
+
- Template reference boards live on tagged templates as named entries such as a
|
|
135
136
|
usual host, product, backdrop, style sample, or per-event speaker. Fixed
|
|
136
137
|
entries attach automatically. Variable entries may be replaced for a run with
|
|
137
138
|
`presetReferenceFills`; each fill REPLACES that entry's pinned images rather
|
|
138
139
|
than appending. Required variable entries block generation until you provide
|
|
139
140
|
at least one image.
|
|
140
|
-
- When a tagged
|
|
141
|
+
- When a tagged template brief names required variable references, collect the
|
|
141
142
|
needed images from the user's attachments or the library and pass
|
|
142
143
|
`presetReferenceFills: [{ referenceId, assetIds }]` to `generate-image` or
|
|
143
144
|
`generate-image-batch`. Board images are additive to brand style references.
|
|
@@ -113,7 +113,7 @@ filtered views.
|
|
|
113
113
|
|
|
114
114
|
For a blog-to-brand-kit workflow: inspect the page, pick the strongest image
|
|
115
115
|
URLs, import each URL into the target `libraryId`, then wire the returned
|
|
116
|
-
`assetId`s into
|
|
116
|
+
`assetId`s into associated Template reference fills or call `set-canonical-logo`
|
|
117
117
|
for the exact logo. Imported assets are stored as `status: "reference"` with
|
|
118
118
|
`sourceUrl` provenance, so downstream generation, preset boards, and logo
|
|
119
119
|
compositing can use them like uploaded reference assets.
|
|
@@ -10,24 +10,26 @@ LLMs — including Gemini Pro — degrade complex logos. They smear gradients, d
|
|
|
10
10
|
## How it works
|
|
11
11
|
|
|
12
12
|
1. The library has a `canonicalLogoUrl` (set via `set-canonical-logo --libraryId --assetId`). The asset's role is `logo_reference`.
|
|
13
|
-
2. **Logo compositing is
|
|
14
|
-
3. **
|
|
13
|
+
2. **Logo compositing is an associated-template option.** A Template carries `includeLogo` (stored in its `settings` and surfaced as a first-class field). Global templates cannot enable it because a canonical logo belongs to a brand kit. When a generation resolves to an associated template with `includeLogo: true`, `generate-image` composites the logo. A generate call's own `includeLogo` arg, when passed, overrides the template for that run; when omitted, the template's value wins.
|
|
14
|
+
3. **Template skeletons generalize logo compositing.** An associated template can carry `settings.skeletonSpec`: background first, generated subject second, foreground layers last. If the skeleton already has a `foreground` layer with `source: "canonicalLogo"`, `includeLogo` is treated as a no-op for that run so the logo is not stamped twice. If the skeleton does not include the logo and `includeLogo` is true, the existing canonical-logo layer is appended at the default upper-right position during compositing.
|
|
15
15
|
4. When logo compositing is on, the prompt envelope adds:
|
|
16
16
|
> Leave a clean uncluttered area in the upper-right for the real brand logo; do not draw or approximate the logo yourself.
|
|
17
17
|
5. Gemini returns an image with empty space in that corner.
|
|
18
18
|
6. `compositeLogo()` from `server/lib/image-processing.ts` (Sharp) loads the canonical logo PNG / SVG, resizes it to ~16% of the image width with reasonable inset, and composites it onto the generated image. Skeleton runs use `applyPresetSkeleton()` at the same seam.
|
|
19
19
|
7. Output: the image with the actual logo, pixel-perfect, vector-quality if the source is SVG.
|
|
20
20
|
|
|
21
|
-
Set `includeLogo` via `create-
|
|
21
|
+
Set `includeLogo` via `create-template` / `update-template` after associating
|
|
22
|
+
the template with a brand kit. The `*-generation-preset` actions are deprecated
|
|
23
|
+
aliases retained for existing threads.
|
|
22
24
|
`generate-image` / `generate-image-batch` stamp the library's pixel-perfect
|
|
23
|
-
canonical logo onto the result when the resolved
|
|
25
|
+
canonical logo onto the result when the resolved template has it on, and it is a
|
|
24
26
|
no-op if the library has no canonical logo. The model never draws the logo
|
|
25
27
|
itself.
|
|
26
28
|
|
|
27
|
-
##
|
|
29
|
+
## Template skeletons
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
edited from `/
|
|
31
|
+
Template skeletons live in `settings.skeletonSpec` on associated templates and
|
|
32
|
+
are edited from `/templates/:templateId`. They composite a
|
|
31
33
|
generated subject onto an uploaded brand background image and optional
|
|
32
34
|
foreground layers.
|
|
33
35
|
|
|
@@ -58,8 +60,8 @@ foreground layers.
|
|
|
58
60
|
|
|
59
61
|
## When to use it
|
|
60
62
|
|
|
61
|
-
- The user turned on "Composite canonical logo"
|
|
62
|
-
- The agent infers the user wants the logo for a one-off (e.g. "make a hero with our brand logo") — pass `includeLogo: true` on that single generate call to override the
|
|
63
|
+
- The user turned on "Composite canonical logo" on an associated template (the template then stamps the logo on every image made with it).
|
|
64
|
+
- The agent infers the user wants the logo for a one-off (e.g. "make a hero with our brand logo") — pass `includeLogo: true` on that single generate call to override the template.
|
|
63
65
|
- The image will appear in a customer-facing context where logo accuracy matters.
|
|
64
66
|
|
|
65
67
|
## When NOT to use it
|
|
@@ -12,9 +12,9 @@ Read the relevant skill in `.agents/skills/` before deeper work:
|
|
|
12
12
|
- `creative-context` for cross-app source reuse, pinned packs, provenance, and
|
|
13
13
|
context opt-out.
|
|
14
14
|
- `library-management` for kits, collections, access, imports, and duplication.
|
|
15
|
-
- `asset-generation` and `image-generation` for generation paths,
|
|
15
|
+
- `asset-generation` and `image-generation` for generation paths, templates,
|
|
16
16
|
composer mentions, reference boards, and embedded text.
|
|
17
|
-
- `logo-composite` for canonical logo compositing and
|
|
17
|
+
- `logo-composite` for canonical logo compositing and template skeletons.
|
|
18
18
|
- `assets-navigation` for routes, tabs, chat surfaces, and `navigate` targets.
|
|
19
19
|
- `agent-engines` for model and engine configuration.
|
|
20
20
|
- `a2a-assets` for MCP/A2A callers, skill install paths, and host rendering.
|
|
@@ -38,12 +38,15 @@ Read the relevant skill in `.agents/skills/` before deeper work:
|
|
|
38
38
|
- Preserve provenance and metadata for generated or imported assets.
|
|
39
39
|
- Use `view-screen` when the active library, selected asset, picker, generation,
|
|
40
40
|
or embed target is unclear.
|
|
41
|
-
- Image work is
|
|
42
|
-
check `list-
|
|
41
|
+
- Image work is template-first. Follow the `creative-context` reuse ladder,
|
|
42
|
+
then check `list-templates` and generate with a matching `templateId`
|
|
43
43
|
instead of ad hoc settings; see `image-generation`.
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
- Templates are global or associated with one brand kit. Only associated
|
|
45
|
+
templates can pin images, skeleton plates, or a canonical logo.
|
|
46
|
+
- When a `template` is tagged, the server embeds its brief inside a
|
|
47
|
+
`<tagged-templates>` block. Internalize it, then pass the `templateId`
|
|
48
|
+
instead of restating saved settings as args. `*-generation-preset` actions
|
|
49
|
+
are deprecated aliases for existing threads.
|
|
47
50
|
- Keep inline previews and picker outputs lightweight; fetch full asset details
|
|
48
51
|
through actions when needed.
|
|
49
52
|
- Use framework sharing/collaboration primitives for ownable assets.
|
|
@@ -55,7 +58,8 @@ Read the relevant skill in `.agents/skills/` before deeper work:
|
|
|
55
58
|
`{ view: "library", selection: "all" | libraryId, tab, scope, folderId, search }`,
|
|
56
59
|
the embedded picker uses
|
|
57
60
|
`{ view: "picker", mediaType, libraryId, query, prompt, aspectRatio }`, and the
|
|
58
|
-
|
|
61
|
+
template gallery uses `{ view: "templates" }`, and an editor uses
|
|
62
|
+
`{ view: "template", templateId }`. Legacy preset navigation still resolves.
|
|
59
63
|
- `creative-context` holds
|
|
60
64
|
`{ contextMode, selectedContextId, currentPackId, pinnedPackId }`. Respect
|
|
61
65
|
`contextMode: "off"` without silently restoring a pack.
|
|
@@ -71,7 +75,7 @@ Uncommon actions stay discoverable through `tool-search`.
|
|
|
71
75
|
|
|
72
76
|
| Action | Purpose |
|
|
73
77
|
| --- | --- |
|
|
74
|
-
| `navigate` | Move the UI to a picker, library, generation, asset,
|
|
78
|
+
| `navigate` | Move the UI to a picker, library, template, generation, asset, or settings surface |
|
|
75
79
|
| `view-screen` | Read current navigation, selection, and visible ids |
|
|
76
80
|
| `list-libraries` / `match-library` | Find or disambiguate a brand kit |
|
|
77
81
|
| `duplicate-library` | Make a private copy of a Brand Kit |
|
|
@@ -79,8 +83,9 @@ Uncommon actions stay discoverable through `tool-search`.
|
|
|
79
83
|
| `import-asset-from-url` | Ingest external brand or blog imagery as a reference asset |
|
|
80
84
|
| `import-style-from-url` | Render a website and merge its design.md-style visual language into a library or collection |
|
|
81
85
|
| `set-canonical-logo` | Pin the kit's pixel-perfect logo |
|
|
82
|
-
| `list-
|
|
83
|
-
| `create-
|
|
86
|
+
| `list-templates` / `get-template` | Find accessible reusable generation recipes |
|
|
87
|
+
| `create-template` / `update-template` | Author a global or brand-kit template |
|
|
88
|
+
| `associate-template` / `duplicate-template` | Move a template's scope or copy it into a kit |
|
|
84
89
|
| `generate-image` / `generate-image-batch` | Generate image candidates (synchronous) |
|
|
85
90
|
| `generate-video` | Generate video, then poll `refresh-generation-run` |
|
|
86
91
|
| `refine-image` / `edit-image` / `restyle-image` | Iterate on an existing asset |
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
All notable user-facing changes to Assets are documented here. Open it any
|
|
4
4
|
time from the command menu (Cmd+K → "What's new") or from Settings.
|
|
5
5
|
|
|
6
|
+
## 2026-08-26
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Templates are now their own surface and can be used across brand kits.
|
|
11
|
+
|
|
6
12
|
## 2026-08-22
|
|
7
13
|
|
|
8
14
|
### Fixed
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
AssetLineageSummary,
|
|
8
8
|
GenerationSessionItemSummary,
|
|
9
9
|
GenerationPresetSummary,
|
|
10
|
+
TemplateSummary,
|
|
10
11
|
GenerationSessionSummary,
|
|
11
12
|
ImageAssetMetadata,
|
|
12
13
|
StyleBrief,
|
|
@@ -196,6 +197,20 @@ export function serializeGenerationPreset(row: any): GenerationPresetSummary {
|
|
|
196
197
|
};
|
|
197
198
|
}
|
|
198
199
|
|
|
200
|
+
export function serializeTemplate(row: any): TemplateSummary {
|
|
201
|
+
const preset = serializeGenerationPreset(row);
|
|
202
|
+
const libraryId = row.libraryId ?? null;
|
|
203
|
+
return {
|
|
204
|
+
...preset,
|
|
205
|
+
libraryId,
|
|
206
|
+
scope: libraryId ? "library" : "global",
|
|
207
|
+
visibility: row.visibility ?? "private",
|
|
208
|
+
ownerEmail: row.ownerEmail,
|
|
209
|
+
accessRole: typeof row.accessRole === "string" ? row.accessRole : undefined,
|
|
210
|
+
libraryTitle: row.libraryTitle ?? null,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
199
214
|
export function serializeGenerationSession(row: any): GenerationSessionSummary {
|
|
200
215
|
const items = Array.isArray(row.items)
|
|
201
216
|
? (row.items as GenerationSessionItemSummary[])
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
accessFilter,
|
|
3
|
+
assertAccess,
|
|
4
|
+
resolveAccess,
|
|
5
|
+
type ShareRole,
|
|
6
|
+
} from "@agent-native/core/sharing";
|
|
7
|
+
import { eq, inArray, or } from "drizzle-orm";
|
|
8
|
+
|
|
9
|
+
import { getDb, schema } from "../server/db/index.js";
|
|
10
|
+
|
|
11
|
+
const roleRank: Record<ShareRole | "owner", number> = {
|
|
12
|
+
viewer: 1,
|
|
13
|
+
commenter: 2,
|
|
14
|
+
editor: 3,
|
|
15
|
+
admin: 4,
|
|
16
|
+
owner: 5,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export async function resolveTemplateAccess(
|
|
20
|
+
id: string,
|
|
21
|
+
minRole: ShareRole | "owner" = "viewer",
|
|
22
|
+
) {
|
|
23
|
+
// guard:allow-unscoped — this helper combines the template ACL with the
|
|
24
|
+
// inherited Brand Kit ACL before exposing the row to its callers.
|
|
25
|
+
const [template] = await getDb()
|
|
26
|
+
.select()
|
|
27
|
+
.from(schema.assetTemplates)
|
|
28
|
+
.where(eq(schema.assetTemplates.id, id))
|
|
29
|
+
.limit(1);
|
|
30
|
+
if (!template) throw new Error("Template not found or not accessible.");
|
|
31
|
+
const ownAccess = await resolveAccess("asset-template", id);
|
|
32
|
+
const libraryAccess = template.libraryId
|
|
33
|
+
? await resolveAccess("asset-library", template.libraryId)
|
|
34
|
+
: null;
|
|
35
|
+
const access =
|
|
36
|
+
libraryAccess &&
|
|
37
|
+
(!ownAccess || roleRank[libraryAccess.role] > roleRank[ownAccess.role])
|
|
38
|
+
? libraryAccess
|
|
39
|
+
: ownAccess;
|
|
40
|
+
if (!access) throw new Error("Template not found or not accessible.");
|
|
41
|
+
if (roleRank[access.role] < roleRank[minRole]) {
|
|
42
|
+
throw new Error(`Template requires ${minRole} access.`);
|
|
43
|
+
}
|
|
44
|
+
return { ...access, resource: template };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function assertTemplateTargetLibraryAccess(
|
|
48
|
+
libraryId: string | null | undefined,
|
|
49
|
+
) {
|
|
50
|
+
if (libraryId) await assertAccess("asset-library", libraryId, "editor");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function accessibleTemplateFilter() {
|
|
54
|
+
const libraries = await getDb()
|
|
55
|
+
.select({ id: schema.assetLibraries.id })
|
|
56
|
+
.from(schema.assetLibraries)
|
|
57
|
+
.where(accessFilter(schema.assetLibraries, schema.assetLibraryShares));
|
|
58
|
+
const templateAccess = accessFilter(
|
|
59
|
+
schema.assetTemplates,
|
|
60
|
+
schema.assetTemplateShares,
|
|
61
|
+
);
|
|
62
|
+
return libraries.length
|
|
63
|
+
? or(
|
|
64
|
+
templateAccess,
|
|
65
|
+
inArray(
|
|
66
|
+
schema.assetTemplates.libraryId,
|
|
67
|
+
libraries.map((library) => library.id),
|
|
68
|
+
),
|
|
69
|
+
)
|
|
70
|
+
: templateAccess;
|
|
71
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ASPECT_RATIOS,
|
|
5
|
+
GENERATION_PRESET_REFERENCE_POLICIES,
|
|
6
|
+
IMAGE_CATEGORIES,
|
|
7
|
+
IMAGE_MODELS,
|
|
8
|
+
IMAGE_SIZES,
|
|
9
|
+
} from "../shared/api.js";
|
|
10
|
+
import { generationPresetSettingsSchema } from "./_generation-preset-settings.js";
|
|
11
|
+
|
|
12
|
+
export const templateFieldsSchema = z.object({
|
|
13
|
+
libraryId: z.string().nullable().optional(),
|
|
14
|
+
collectionId: z.string().nullable().optional(),
|
|
15
|
+
title: z.string().min(1).optional(),
|
|
16
|
+
description: z.string().nullable().optional(),
|
|
17
|
+
category: z.enum(IMAGE_CATEGORIES).optional(),
|
|
18
|
+
promptTemplate: z.string().nullable().optional(),
|
|
19
|
+
aspectRatio: z.enum(ASPECT_RATIOS).optional(),
|
|
20
|
+
imageSize: z.enum(IMAGE_SIZES).optional(),
|
|
21
|
+
model: z.enum(IMAGE_MODELS).optional(),
|
|
22
|
+
textPolicy: z.string().optional(),
|
|
23
|
+
referencePolicy: z.enum(GENERATION_PRESET_REFERENCE_POLICIES).optional(),
|
|
24
|
+
includeLogo: z.coerce.boolean().optional(),
|
|
25
|
+
settings: generationPresetSettingsSchema.optional(),
|
|
26
|
+
sortOrder: z.coerce.number().optional(),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export function templateHasPins(settings: Record<string, unknown>) {
|
|
30
|
+
const refs = Array.isArray(settings.presetReferences)
|
|
31
|
+
? settings.presetReferences
|
|
32
|
+
: [];
|
|
33
|
+
const pinned = refs.flatMap((reference) => {
|
|
34
|
+
if (!reference || typeof reference !== "object") return [];
|
|
35
|
+
const entry = reference as {
|
|
36
|
+
id?: unknown;
|
|
37
|
+
label?: unknown;
|
|
38
|
+
assetIds?: unknown;
|
|
39
|
+
};
|
|
40
|
+
if (!Array.isArray(entry.assetIds) || !entry.assetIds.length) return [];
|
|
41
|
+
const name =
|
|
42
|
+
typeof entry.label === "string" && entry.label.trim()
|
|
43
|
+
? entry.label.trim()
|
|
44
|
+
: typeof entry.id === "string" && entry.id
|
|
45
|
+
? entry.id
|
|
46
|
+
: "unnamed reference";
|
|
47
|
+
return [`reference \"${name}\"`];
|
|
48
|
+
});
|
|
49
|
+
const skeleton = settings.skeletonSpec ? ["skeletonSpec"] : [];
|
|
50
|
+
return [...pinned, ...skeleton];
|
|
51
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core/action";
|
|
2
|
+
import { eq } from "drizzle-orm";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import { getDb, schema } from "../server/db/index.js";
|
|
6
|
+
import { nowIso, parseJson } from "../server/lib/json.js";
|
|
7
|
+
import { serializeTemplate } from "./_helpers.js";
|
|
8
|
+
import {
|
|
9
|
+
assertTemplateTargetLibraryAccess,
|
|
10
|
+
resolveTemplateAccess,
|
|
11
|
+
} from "./_template-access.js";
|
|
12
|
+
import { templateHasPins } from "./_template-input.js";
|
|
13
|
+
|
|
14
|
+
export default defineAction({
|
|
15
|
+
description: "Move an asset template between global scope and one Brand Kit.",
|
|
16
|
+
schema: z.object({ id: z.string(), libraryId: z.string().nullable() }),
|
|
17
|
+
run: async ({ id, libraryId }) => {
|
|
18
|
+
const template = (await resolveTemplateAccess(id, "editor")).resource;
|
|
19
|
+
await assertTemplateTargetLibraryAccess(libraryId);
|
|
20
|
+
const pins = templateHasPins(
|
|
21
|
+
parseJson<Record<string, unknown>>(template.settings, {}),
|
|
22
|
+
);
|
|
23
|
+
if (libraryId !== template.libraryId && pins.length) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
`Clear pinned template settings before changing Brand Kits: ${pins.join(", ")}.`,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
const updates = {
|
|
29
|
+
libraryId,
|
|
30
|
+
...(libraryId !== template.libraryId ? { collectionId: null } : {}),
|
|
31
|
+
updatedAt: nowIso(),
|
|
32
|
+
};
|
|
33
|
+
await getDb()
|
|
34
|
+
.update(schema.assetTemplates)
|
|
35
|
+
.set(updates)
|
|
36
|
+
.where(eq(schema.assetTemplates.id, id));
|
|
37
|
+
return serializeTemplate({ ...template, ...updates });
|
|
38
|
+
},
|
|
39
|
+
});
|