howone 0.1.30 → 0.1.32
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/package.json +1 -1
- package/templates/vite/.howone/skills/howone/01-architect/01-app-generation.md +138 -176
- package/templates/vite/.howone/skills/howone/01-architect/02-manifest-codegen.md +2 -2
- package/templates/vite/.howone/skills/howone/{02-database → 02-entity-schema}/01-schema-design.md +12 -30
- package/templates/vite/.howone/skills/howone/02-entity-schema/02-schema-operations.md +329 -0
- package/templates/vite/.howone/skills/howone/02-entity-schema/03-access-models.md +151 -0
- package/templates/vite/.howone/skills/howone/02-entity-schema/04-query-contracts.md +123 -0
- package/templates/vite/.howone/skills/howone/02-entity-schema/05-ai-persistence-patterns.md +255 -0
- package/templates/vite/.howone/skills/howone/{04-ai → 03-ai-capabilities}/01-ai-capability-architecture.md +42 -36
- package/templates/vite/.howone/skills/howone/{04-ai → 03-ai-capabilities}/02-workflow-contract-rules.md +5 -4
- package/templates/vite/.howone/skills/howone/{04-ai/04-service-capability-catalog.md → 03-ai-capabilities/03-service-capability-catalog.md} +15 -11
- package/templates/vite/.howone/skills/howone/03-ai-capabilities/04-workflow-operations.md +141 -0
- package/templates/vite/.howone/skills/howone/{04-ai/06-ai-feature-playbooks.md → 03-ai-capabilities/05-ai-feature-playbooks.md} +8 -29
- package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/01-client-setup.md +7 -6
- package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/07-ai-action-calls.md +5 -5
- package/templates/vite/.howone/skills/howone/{04-ai/03-ai-sdk-handoff.md → 04-app-sdk/08-ai-manifest-handoff.md} +8 -7
- package/templates/vite/.howone/skills/howone/{03-sdk/08-extension-boundaries.md → 04-app-sdk/09-extension-boundaries.md} +1 -1
- package/templates/vite/.howone/skills/howone/{02-database/03-data-access-patterns.md → 04-app-sdk/11-entity-data-access-patterns.md} +4 -4
- package/templates/vite/.howone/skills/howone/{02-database/04-query-dsl-and-responses.md → 04-app-sdk/12-query-dsl-and-responses.md} +1 -1
- package/templates/vite/.howone/skills/howone/SKILL.md +137 -133
- package/templates/vite/.howone/skills/howone/agents/openai.yaml +3 -3
- package/templates/vite/AGENTS.md +2 -2
- package/templates/vite/.howone/skills/howone/02-database/02-schema-operations.md +0 -398
- package/templates/vite/.howone/skills/howone/02-database/05-ai-persistence-patterns.md +0 -372
- package/templates/vite/.howone/skills/howone/04-ai/05-workflow-operations.md +0 -256
- /package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/02-entity-operations.md +0 -0
- /package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/03-auth.md +0 -0
- /package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/04-react-integration.md +0 -0
- /package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/05-file-upload.md +0 -0
- /package/templates/vite/.howone/skills/howone/{03-sdk → 04-app-sdk}/06-raw-http.md +0 -0
- /package/templates/vite/.howone/skills/howone/{03-sdk/09-workflow-execute-sse.md → 04-app-sdk/10-workflow-execute-sse.md} +0 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# AI Persistence Entity Patterns
|
|
2
|
+
|
|
3
|
+
Use this reference after the AI output schema is known and the product needs durable data:
|
|
4
|
+
generation history, saved results, reports, retryable jobs, share pages, or user libraries.
|
|
5
|
+
|
|
6
|
+
This is a backend entity design reference. It does not define SDK calls. App-side execution and
|
|
7
|
+
persistence code belongs in `04-app-sdk/07-ai-action-calls.md` and
|
|
8
|
+
`04-app-sdk/08-ai-manifest-handoff.md`.
|
|
9
|
+
|
|
10
|
+
## Core Boundary
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
AI capability outputSchema != database entity schema
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The AI output schema is the workflow return contract. The database entity schema is the product
|
|
17
|
+
record contract. Persist only fields the product needs after refresh, across sessions, in lists, or
|
|
18
|
+
on public pages.
|
|
19
|
+
|
|
20
|
+
For every AI output field, decide:
|
|
21
|
+
|
|
22
|
+
| Question | Persist? | Entity design |
|
|
23
|
+
|---|---:|---|
|
|
24
|
+
| User must see it after refresh | yes | explicit field |
|
|
25
|
+
| It appears in history/library/search | yes | field + index if queried |
|
|
26
|
+
| It is needed for retry/resume | yes | input/options/status fields |
|
|
27
|
+
| It is only a streaming/intermediate chunk | no | runtime/UI state |
|
|
28
|
+
| It is provider debug metadata | usually no | logs, not product records |
|
|
29
|
+
| It is sensitive internal/provider data | usually no | omit or keep private-only |
|
|
30
|
+
|
|
31
|
+
## Pending-First Record Model
|
|
32
|
+
|
|
33
|
+
For long-running or user-visible AI jobs, design an entity that can represent pending, completed,
|
|
34
|
+
and failed states. The app may create a pending record before workflow execution, then update it
|
|
35
|
+
after completion or failure.
|
|
36
|
+
|
|
37
|
+
Required contract pieces:
|
|
38
|
+
|
|
39
|
+
- original user input or durable input reference;
|
|
40
|
+
- `status`;
|
|
41
|
+
- output fields for completed display;
|
|
42
|
+
- failure fields for history/retry;
|
|
43
|
+
- timestamps for list ordering and stale-job handling.
|
|
44
|
+
|
|
45
|
+
Status field:
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"status": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"description": "pending | running | completed | failed | canceled",
|
|
52
|
+
"default": "pending"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Rules:
|
|
58
|
+
|
|
59
|
+
- Do not infer completion only from `resultUrl`, `summary`, or another output field.
|
|
60
|
+
- Keep failed records when the product has history or retry UX.
|
|
61
|
+
- If pending/running records are shown from persisted data, define how stale records are recovered.
|
|
62
|
+
- Do not store raw event streams unless the entity explicitly needs them.
|
|
63
|
+
|
|
64
|
+
## Minimal Generation History Entity
|
|
65
|
+
|
|
66
|
+
Use for image, text, report, music, video, or similar generation history.
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"name": "Generation",
|
|
71
|
+
"type": "object",
|
|
72
|
+
"properties": {
|
|
73
|
+
"prompt": { "type": "string" },
|
|
74
|
+
"status": { "type": "string", "default": "pending" },
|
|
75
|
+
"resultUrl": { "type": ["string", "null"], "default": null },
|
|
76
|
+
"resultText": { "type": ["string", "null"], "default": null },
|
|
77
|
+
"errorMessage": { "type": ["string", "null"], "default": null },
|
|
78
|
+
"requestedAt": { "type": "date" },
|
|
79
|
+
"completedAt": { "type": ["date", "null"], "default": null }
|
|
80
|
+
},
|
|
81
|
+
"required": ["prompt", "status", "requestedAt"],
|
|
82
|
+
"access": {
|
|
83
|
+
"authenticated": { "read": "own", "create": "own", "update": "own", "delete": "own" },
|
|
84
|
+
"public": { "read": "none", "create": "none", "update": "none", "delete": "none" }
|
|
85
|
+
},
|
|
86
|
+
"indexes": [
|
|
87
|
+
{ "name": "owner_updated", "fields": ["updatedDate"], "scope": "owner" },
|
|
88
|
+
{ "name": "owner_status_updated", "fields": ["status", "updatedDate"], "scope": "owner" }
|
|
89
|
+
],
|
|
90
|
+
"performance": {
|
|
91
|
+
"defaultLimit": 20,
|
|
92
|
+
"maxLimit": 100,
|
|
93
|
+
"allowedSorts": ["updatedDate", "requestedAt"]
|
|
94
|
+
},
|
|
95
|
+
"presentation": {
|
|
96
|
+
"titleField": "prompt",
|
|
97
|
+
"subtitleField": "status"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Prefer separate product fields over one opaque `result` object when the UI lists, filters, previews,
|
|
103
|
+
or shares the output. Use an object field only for genuinely nested product-level structured data.
|
|
104
|
+
|
|
105
|
+
## Structured Analysis Report Entity
|
|
106
|
+
|
|
107
|
+
Use when AI returns a report users browse later.
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"name": "AnalysisReport",
|
|
112
|
+
"type": "object",
|
|
113
|
+
"properties": {
|
|
114
|
+
"sourceTitle": { "type": "string" },
|
|
115
|
+
"sourceUrl": { "type": ["string", "null"], "default": null },
|
|
116
|
+
"status": { "type": "string", "default": "pending" },
|
|
117
|
+
"summary": { "type": ["string", "null"], "default": null },
|
|
118
|
+
"insights": { "type": "array", "default": [] },
|
|
119
|
+
"score": { "type": ["number", "null"], "default": null },
|
|
120
|
+
"errorMessage": { "type": ["string", "null"], "default": null },
|
|
121
|
+
"requestedAt": { "type": "date" },
|
|
122
|
+
"completedAt": { "type": ["date", "null"], "default": null }
|
|
123
|
+
},
|
|
124
|
+
"required": ["sourceTitle", "status", "requestedAt"],
|
|
125
|
+
"access": {
|
|
126
|
+
"authenticated": { "read": "own", "create": "own", "update": "own", "delete": "own" },
|
|
127
|
+
"public": { "read": "none", "create": "none", "update": "none", "delete": "none" }
|
|
128
|
+
},
|
|
129
|
+
"indexes": [
|
|
130
|
+
{ "name": "owner_updated", "fields": ["updatedDate"], "scope": "owner" },
|
|
131
|
+
{ "name": "owner_score_updated", "fields": ["score", "updatedDate"], "scope": "owner" }
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Mapping rule:
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
workflow input.sourceTitle -> AnalysisReport.sourceTitle
|
|
140
|
+
workflow input.sourceUrl -> AnalysisReport.sourceUrl
|
|
141
|
+
workflow output.summary -> AnalysisReport.summary
|
|
142
|
+
workflow output.insights -> AnalysisReport.insights
|
|
143
|
+
workflow output.score -> AnalysisReport.score
|
|
144
|
+
runtime failure -> AnalysisReport.errorMessage
|
|
145
|
+
runtime completed -> AnalysisReport.completedAt
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Do not save the whole workflow envelope unless the product explicitly needs a private object field
|
|
149
|
+
for audit/debug.
|
|
150
|
+
|
|
151
|
+
## Public Share Split
|
|
152
|
+
|
|
153
|
+
For public AI result pages, split private history from public share data:
|
|
154
|
+
|
|
155
|
+
- private `Generation` stores prompts, failures, drafts, internal metadata, and user history;
|
|
156
|
+
- public/scoped `SharedGeneration` stores only curated fields for anonymous viewing.
|
|
157
|
+
|
|
158
|
+
Scoped public share entity:
|
|
159
|
+
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"name": "SharedGeneration",
|
|
163
|
+
"type": "object",
|
|
164
|
+
"properties": {
|
|
165
|
+
"shareId": {
|
|
166
|
+
"type": "string",
|
|
167
|
+
"autoGenerate": { "strategy": "uuid" }
|
|
168
|
+
},
|
|
169
|
+
"title": { "type": "string" },
|
|
170
|
+
"resultUrl": { "type": "string" },
|
|
171
|
+
"active": { "type": "boolean", "default": true },
|
|
172
|
+
"sourceGenerationId": { "type": "string" }
|
|
173
|
+
},
|
|
174
|
+
"required": ["shareId", "title", "resultUrl", "active", "sourceGenerationId"],
|
|
175
|
+
"access": {
|
|
176
|
+
"authenticated": { "read": "own", "create": "own", "update": "own", "delete": "own" },
|
|
177
|
+
"public": {
|
|
178
|
+
"read": "scoped",
|
|
179
|
+
"create": "none",
|
|
180
|
+
"update": "none",
|
|
181
|
+
"delete": "none",
|
|
182
|
+
"requiredScopes": ["shareId"],
|
|
183
|
+
"allowedFilters": ["shareId", "active"],
|
|
184
|
+
"allowedSorts": ["updatedDate"],
|
|
185
|
+
"defaultLimit": 1,
|
|
186
|
+
"maxLimit": 1
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"indexes": [
|
|
190
|
+
{ "name": "share_id_unique", "fields": ["shareId"], "unique": true },
|
|
191
|
+
{ "name": "owner_updated", "fields": ["updatedDate"], "scope": "owner" }
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Never make the main private generation history public just to support share pages.
|
|
197
|
+
|
|
198
|
+
## Retry And Resume Fields
|
|
199
|
+
|
|
200
|
+
If retry is part of the product, persist enough input fields to rebuild the workflow request:
|
|
201
|
+
|
|
202
|
+
- prompt/source content reference;
|
|
203
|
+
- selected style/mode/options;
|
|
204
|
+
- uploaded file URLs or file IDs;
|
|
205
|
+
- status and error message;
|
|
206
|
+
- requested/completed timestamps.
|
|
207
|
+
|
|
208
|
+
Do not persist:
|
|
209
|
+
|
|
210
|
+
- auth/session/token values;
|
|
211
|
+
- raw uploaded browser bytes;
|
|
212
|
+
- temporary component state;
|
|
213
|
+
- raw streaming chunks;
|
|
214
|
+
- provider secrets;
|
|
215
|
+
- hidden system prompts or internal prompts.
|
|
216
|
+
|
|
217
|
+
Prefer a new retry record for history-oriented products. Prefer updating the same record only when
|
|
218
|
+
retry semantically replaces the original attempt.
|
|
219
|
+
|
|
220
|
+
## Field Mapping Checklist
|
|
221
|
+
|
|
222
|
+
Before app implementation, write the mapping explicitly:
|
|
223
|
+
|
|
224
|
+
```text
|
|
225
|
+
workflow input.prompt -> Generation.prompt
|
|
226
|
+
workflow input.style -> Generation.style
|
|
227
|
+
workflow output.imageUrl -> Generation.resultUrl
|
|
228
|
+
workflow output.caption -> Generation.resultText
|
|
229
|
+
workflow error.message -> Generation.errorMessage
|
|
230
|
+
runtime request started -> Generation.requestedAt
|
|
231
|
+
runtime request completed -> Generation.completedAt
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
If a workflow output has no mapping, decide whether it is intentionally transient or the entity
|
|
235
|
+
schema is missing a product field.
|
|
236
|
+
|
|
237
|
+
## Access Checklist
|
|
238
|
+
|
|
239
|
+
| Product behavior | Entity access |
|
|
240
|
+
|---|---|
|
|
241
|
+
| User-only private generation history | authenticated own, public none |
|
|
242
|
+
| Shared authenticated library | authenticated all, public none |
|
|
243
|
+
| Anonymous public gallery | public list with safe fields only |
|
|
244
|
+
| One public share link | public scoped with share id |
|
|
245
|
+
| Public submission to AI queue | public create only with anti-abuse constraints |
|
|
246
|
+
|
|
247
|
+
## Persistence Checklist
|
|
248
|
+
|
|
249
|
+
- AI output schema is fixed before persistence schema design.
|
|
250
|
+
- Entity stores product fields, not workflow internals.
|
|
251
|
+
- Status and failure fields exist for long-running jobs.
|
|
252
|
+
- Retry/resume input fields are durable.
|
|
253
|
+
- Public share data is split from private history.
|
|
254
|
+
- Indexes match history/share/list query patterns.
|
|
255
|
+
- SDK implementation begins only after database and AI manifests are synced.
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# AI Capability Architecture
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
**Track:** `03-ai-capabilities/` — capability/workflow **design** only; SDK calls live in `04-app-sdk/`.
|
|
4
|
+
|
|
5
|
+
Use this reference when the user needs HowOne platform AI (verify `03-service-capability-catalog.md` first).
|
|
5
6
|
|
|
6
7
|
This file answers: **what AI layer should be designed, in what order, and where each responsibility
|
|
7
8
|
belongs?** For schema details read `02-workflow-contract-rules.md`. For workflow service calls read
|
|
8
|
-
`
|
|
9
|
+
`04-workflow-operations.md`.
|
|
9
10
|
|
|
10
11
|
## Platform Mental Model
|
|
11
12
|
|
|
@@ -15,9 +16,9 @@ HowOne AI has five distinct layers:
|
|
|
15
16
|
|---|---|---|
|
|
16
17
|
| Product feature | User-facing goal, UX states, persistence decision | workflow internals |
|
|
17
18
|
| AI capability contract | `name`, `description`, `inputSchema`, `outputSchema`, `outputEntityName`, versions, manifest | database CRUD, UI, auth |
|
|
18
|
-
| External workflow implementation | generated/edited workflow graph behind a `workflowId` | app schema, frontend state |
|
|
19
|
-
| Status/background layer |
|
|
20
|
-
| SDK
|
|
19
|
+
| External workflow implementation | generated/edited workflow graph behind a manifest `workflowId`/EAX `config_id` | app schema, frontend state |
|
|
20
|
+
| Status/background layer | job/task polling, completed/failed state, submitted config mapping | SDK binding source |
|
|
21
|
+
| SDK handoff | synced manifest action names, workflow IDs, input/output schemas | workflow generation |
|
|
21
22
|
|
|
22
23
|
Do not collapse these layers. The common mistakes are:
|
|
23
24
|
|
|
@@ -33,10 +34,9 @@ Do not collapse these layers. The common mistakes are:
|
|
|
33
34
|
user request = intent
|
|
34
35
|
agent AI contract proposal = draft
|
|
35
36
|
applied AI capability version = validated contract
|
|
36
|
-
.howone/ai/manifest.json = local synced source for SDK codegen
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
frontend UI = SDK consumer
|
|
37
|
+
.howone/ai/manifest.json = local synced source for workflow submit and later SDK codegen
|
|
38
|
+
external-ai-capability result = job/task/config mapping and possible manifest workflowId update
|
|
39
|
+
SDK/UI implementation = separate app-sdk track after AI design is complete
|
|
40
40
|
entity schema = persistence contract, separate from AI contract
|
|
41
41
|
```
|
|
42
42
|
|
|
@@ -46,19 +46,18 @@ Never generate SDK bindings from the user prompt or from an unsynced draft.
|
|
|
46
46
|
|
|
47
47
|
Use this flow for new AI features:
|
|
48
48
|
|
|
49
|
-
1. Classify the feature using `
|
|
49
|
+
1. Classify the feature using `03-ai-capabilities/03-service-capability-catalog.md`.
|
|
50
50
|
2. Decide whether the feature is supported. If not supported, stop and explain the missing capability.
|
|
51
51
|
3. Decide one workflow per user-facing feature. Use two workflows only for RAG.
|
|
52
52
|
4. Design `inputSchema` and `outputSchema` using `02-workflow-contract-rules.md`.
|
|
53
|
-
5.
|
|
53
|
+
5. Apply the AI capability patch through the capability tool.
|
|
54
54
|
6. Sync `.howone/ai/manifest.json`.
|
|
55
|
-
7. Submit workflow create through `external-ai-capability`
|
|
56
|
-
8. Store returned
|
|
55
|
+
7. Submit workflow create/update through `external-ai-capability` from the synced manifest.
|
|
56
|
+
8. Store returned job/task IDs and submitted config IDs for polling/debugging.
|
|
57
57
|
9. Poll status until `completed` or `failed`.
|
|
58
|
-
10.
|
|
59
|
-
11.
|
|
60
|
-
12.
|
|
61
|
-
13. If output must persist, design entity schema and use `runAiActionAndPersist()` when appropriate.
|
|
58
|
+
10. Re-read `.howone/ai/manifest.json`; update operations may have written fresh `workflowId` values.
|
|
59
|
+
11. Leave AI design. If app code must call the workflow, read the SDK track and generate bindings.
|
|
60
|
+
12. If output must persist, design entity schema after the output contract is fixed.
|
|
62
61
|
|
|
63
62
|
Do not submit external workflow create/update from a hand-written schema. It should come from the
|
|
64
63
|
synced manifest.
|
|
@@ -70,7 +69,7 @@ synced manifest.
|
|
|
70
69
|
| New AI feature, no manifest entry | create AI capability, sync manifest, submit workflow create |
|
|
71
70
|
| Manifest entry exists but no workflow created yet | submit workflow create from manifest |
|
|
72
71
|
| User asks to change input/output contract | update capability contract first, sync, then submit workflow update |
|
|
73
|
-
| User asks to improve behavior only | submit workflow update with `
|
|
72
|
+
| User asks to improve behavior only | submit workflow update with `updates[]` and `updatePrompt` |
|
|
74
73
|
| User asks to save outputs/history | design/update database entity after AI output contract is known |
|
|
75
74
|
| User asks for public share of AI result | private history entity + public scoped share entity |
|
|
76
75
|
|
|
@@ -80,23 +79,30 @@ Create external workflow when:
|
|
|
80
79
|
|
|
81
80
|
- capability has a `workflowId`;
|
|
82
81
|
- no confirmed external implementation exists;
|
|
83
|
-
-
|
|
82
|
+
- the manifest `workflowId` has not already been submitted as an implementation config.
|
|
84
83
|
|
|
85
84
|
Update external workflow when:
|
|
86
85
|
|
|
87
86
|
- an external implementation exists;
|
|
88
|
-
- the status layer previously returned `payload.workflow_details.new_workflow_config_id`;
|
|
89
87
|
- you have a concrete `updatePrompt`.
|
|
88
|
+
- `external-ai-capability` can read the current manifest `workflowId`.
|
|
90
89
|
|
|
91
|
-
`
|
|
90
|
+
Current `external-ai-capability` semantics:
|
|
92
91
|
|
|
93
92
|
```text
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
create:
|
|
94
|
+
config_id = manifest capability.workflowId
|
|
95
|
+
mode = create
|
|
96
|
+
|
|
97
|
+
update:
|
|
98
|
+
previous config = current manifest capability.workflowId
|
|
99
|
+
new config = freshly generated UUID
|
|
100
|
+
manifest = rewritten so capability.workflowId is the fresh UUID
|
|
97
101
|
```
|
|
98
102
|
|
|
99
|
-
|
|
103
|
+
The SDK execution binding uses the manifest `workflowId`, which is the EAX config id. After update,
|
|
104
|
+
the new manifest `workflowId` is the only value that should be copied into `src/lib/sdk.ts`.
|
|
105
|
+
Do not invent IDs; let the AI design/sync/external workflow tools generate and persist them.
|
|
100
106
|
|
|
101
107
|
## Workflow Count Rule
|
|
102
108
|
|
|
@@ -136,18 +142,18 @@ Workflow must not do:
|
|
|
136
142
|
- owner assignment or permissions;
|
|
137
143
|
- app navigation, UI state, toast, or modal logic.
|
|
138
144
|
|
|
139
|
-
If the product needs durable history,
|
|
145
|
+
If the product needs durable history, design entity persistence outside the workflow:
|
|
140
146
|
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
run: (input) => howone.ai.generateImage.run(input),
|
|
147
|
-
mapCompleted: ({ output }) => ({ status: 'completed', resultUrl: output.generated_image_url }),
|
|
148
|
-
})
|
|
147
|
+
```text
|
|
148
|
+
workflow input.prompt -> Generation.prompt
|
|
149
|
+
workflow output.imageUrl -> Generation.resultUrl
|
|
150
|
+
runtime failure -> Generation.errorMessage
|
|
151
|
+
runtime status -> Generation.status
|
|
149
152
|
```
|
|
150
153
|
|
|
154
|
+
After AI and database manifests are synced, app implementation can read the SDK track to wire the
|
|
155
|
+
runtime calls.
|
|
156
|
+
|
|
151
157
|
## Unsupported AI Behavior
|
|
152
158
|
|
|
153
159
|
If a user explicitly requires behavior not available in the workflow service, stop that AI path.
|
|
@@ -201,5 +207,5 @@ Before editing files:
|
|
|
201
207
|
- Input and output property names do not overlap.
|
|
202
208
|
- Text output descriptions specify language behavior.
|
|
203
209
|
- Persistence is modeled as entity schema, not workflow CRUD.
|
|
204
|
-
- `workflowId
|
|
210
|
+
- `workflowId` / EAX `config_id` values are generated by tools and not guessed.
|
|
205
211
|
- SDK binding will be generated only after manifest sync.
|
|
@@ -4,7 +4,7 @@ Use this reference when designing `capability.description`, `inputSchema`, `outp
|
|
|
4
4
|
`outputEntityName` for HowOne AI workflows.
|
|
5
5
|
|
|
6
6
|
These rules come from `docs/ai-worlfow-guide-schema.md`. Violating them can make the workflow
|
|
7
|
-
service reject the request or produce a workflow
|
|
7
|
+
service reject the request or produce a workflow the runtime cannot execute reliably.
|
|
8
8
|
|
|
9
9
|
## Contract Shape
|
|
10
10
|
|
|
@@ -122,7 +122,8 @@ Forbidden:
|
|
|
122
122
|
- inline PDF/image/audio bytes;
|
|
123
123
|
- browser upload logic in workflow.
|
|
124
124
|
|
|
125
|
-
The app uploads first
|
|
125
|
+
The app uploads first, then passes the resulting URL to the workflow. File upload helpers belong to
|
|
126
|
+
the SDK track.
|
|
126
127
|
|
|
127
128
|
## Output Minimalism
|
|
128
129
|
|
|
@@ -227,8 +228,8 @@ Forbidden in capability descriptions and schemas:
|
|
|
227
228
|
Instead:
|
|
228
229
|
|
|
229
230
|
1. workflow returns output fields;
|
|
230
|
-
2.
|
|
231
|
-
3.
|
|
231
|
+
2. app code persists through the entity runtime after SDK handoff;
|
|
232
|
+
3. durable fields map to the entity contract.
|
|
232
233
|
|
|
233
234
|
## External Data Assumptions
|
|
234
235
|
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
# Service Capability Catalog
|
|
2
2
|
|
|
3
|
-
Use this reference
|
|
4
|
-
service
|
|
3
|
+
Use this reference **only** for HowOne **workflow-service AI** feasibility. It lists what the current
|
|
4
|
+
workflow service supports—not everything a full product may use.
|
|
5
|
+
|
|
6
|
+
Infrastructure or products the user operates themselves (clusters, custom servers, third-party
|
|
7
|
+
APIs, etc.) are **app-owned** per `01-architect/01-app-generation.md`. They are out of scope for
|
|
8
|
+
this catalog and must not be rejected as "AI not supported" when the user only needs to connect to them in app code.
|
|
5
9
|
|
|
6
10
|
Source: `docs/ai-capability.md`.
|
|
7
11
|
|
|
@@ -268,14 +272,14 @@ Rules:
|
|
|
268
272
|
| Video -> Image edit -> Video | extract frame, edit frame, use as next reference |
|
|
269
273
|
| RAG document chat | indexing workflow + query workflow |
|
|
270
274
|
|
|
271
|
-
##
|
|
275
|
+
## Platform AI stop (catalog boundary)
|
|
276
|
+
|
|
277
|
+
Stop **platform AI design** (do not invent capabilities) when the requirement:
|
|
272
278
|
|
|
273
|
-
|
|
279
|
+
- has no matching capability family in this catalog or detailed sections below;
|
|
280
|
+
- needs behavior the workflow service cannot perform per contract rules in `02-workflow-contract-rules.md`;
|
|
281
|
+
- violates workflow input/output constraints (e.g. persistence or app CRUD inside the workflow contract);
|
|
282
|
+
- exceeds documented service limits after you read the relevant section.
|
|
274
283
|
|
|
275
|
-
|
|
276
|
-
-
|
|
277
|
-
- raw file bytes/base64 in workflow;
|
|
278
|
-
- database CRUD inside workflow;
|
|
279
|
-
- unsupported provider-specific model guarantees;
|
|
280
|
-
- content disallowed by moderation;
|
|
281
|
-
- long video generation in one call beyond service limits.
|
|
284
|
+
Explain the gap by **missing catalog/contract support**, not by naming the user's stack. Offer the
|
|
285
|
+
closest listed capability or ask to narrow the product ask. App-owned integrations remain allowed in parallel.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Workflow Operations
|
|
2
|
+
|
|
3
|
+
Use this reference when submitting HowOne external AI workflow create/update operations through
|
|
4
|
+
`external-ai-capability`. This is an AI workflow design reference, not an app SDK guide.
|
|
5
|
+
|
|
6
|
+
## Current Tool Contract
|
|
7
|
+
|
|
8
|
+
Do not hand-build raw workflow HTTP requests in generated app work. Use `external-ai-capability`
|
|
9
|
+
after `.howone/ai/manifest.json` has been synced.
|
|
10
|
+
|
|
11
|
+
The tool performs:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
POST /workflows
|
|
15
|
+
GET /jobs/{job_id}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The tool reads the synced manifest and submits operations for selected capabilities.
|
|
19
|
+
|
|
20
|
+
## Create
|
|
21
|
+
|
|
22
|
+
Use create when the capability has a synced manifest entry and no external implementation has been
|
|
23
|
+
submitted for its current `workflowId`.
|
|
24
|
+
|
|
25
|
+
Tool input:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"cwd": "<app-root>",
|
|
30
|
+
"capabilityNames": ["summarizeDocument"]
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Tool behavior:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
config_id = manifest.capabilities[].workflowId
|
|
38
|
+
mode = create
|
|
39
|
+
capability = synced manifest capability contract
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Do not generate a second UUID for create. The AI capability design/sync path already produced the
|
|
43
|
+
manifest `workflowId`.
|
|
44
|
+
|
|
45
|
+
## Update
|
|
46
|
+
|
|
47
|
+
Use update when the external implementation exists and the user asks to change workflow behavior or
|
|
48
|
+
to regenerate implementation for a changed contract.
|
|
49
|
+
|
|
50
|
+
Tool input:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"cwd": "<app-root>",
|
|
55
|
+
"updates": [
|
|
56
|
+
{
|
|
57
|
+
"capabilityName": "summarizeDocument",
|
|
58
|
+
"updatePrompt": "Support concise bullet-point summaries when the user asks for bullet format."
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Tool behavior:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
previous config = current manifest capability.workflowId
|
|
68
|
+
new config = freshly generated UUID
|
|
69
|
+
mode = update
|
|
70
|
+
manifest = rewritten so capability.workflowId is the fresh UUID
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
After update, re-read `.howone/ai/manifest.json`. The new manifest `workflowId` is the value used by
|
|
74
|
+
SDK bindings and future execution.
|
|
75
|
+
|
|
76
|
+
Do not pass stale `workflowConfigID` values from old docs or older status payloads. The current
|
|
77
|
+
tool owns config rotation and manifest write-back.
|
|
78
|
+
|
|
79
|
+
## Selection Rules
|
|
80
|
+
|
|
81
|
+
- `capabilityNames` limits create operations.
|
|
82
|
+
- `updates[]` limits update operations.
|
|
83
|
+
- If `updates[]` is provided without `capabilityNames`, only those update capabilities are selected.
|
|
84
|
+
- Do not submit every capability when the user asked to update one behavior.
|
|
85
|
+
|
|
86
|
+
## Status And Results
|
|
87
|
+
|
|
88
|
+
The tool may return immediately when a host poller is available. Preserve:
|
|
89
|
+
|
|
90
|
+
- `jobId`;
|
|
91
|
+
- `taskId` / `requestId` when present;
|
|
92
|
+
- `submittedConfigId`;
|
|
93
|
+
- `previousConfigId` for updates;
|
|
94
|
+
- `manifestUpdates` mapping old workflow IDs to new workflow IDs.
|
|
95
|
+
|
|
96
|
+
Terminal result meaning:
|
|
97
|
+
|
|
98
|
+
| Status | Meaning |
|
|
99
|
+
|---|---|
|
|
100
|
+
| `submitted` | background poller will continue |
|
|
101
|
+
| `running` / `queued` | not terminal |
|
|
102
|
+
| `completed` | workflow operation completed |
|
|
103
|
+
| `failed` / `canceled` / `timed_out` | report error and do not pretend workflow is ready |
|
|
104
|
+
|
|
105
|
+
## Standard Flow
|
|
106
|
+
|
|
107
|
+
New AI feature:
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
ai-capability-design apply_capability_patch
|
|
111
|
+
sync_ai_artifacts
|
|
112
|
+
external-ai-capability { cwd, capabilityNames }
|
|
113
|
+
read .howone/ai/manifest.json
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Schema-changing AI update:
|
|
117
|
+
|
|
118
|
+
```text
|
|
119
|
+
ai-capability-design apply_capability_patch
|
|
120
|
+
sync_ai_artifacts
|
|
121
|
+
external-ai-capability { cwd, updates: [{ capabilityName, updatePrompt }] }
|
|
122
|
+
read .howone/ai/manifest.json
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Behavior-only update:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
external-ai-capability { cwd, updates: [{ capabilityName, updatePrompt }] }
|
|
129
|
+
read .howone/ai/manifest.json
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
SDK/code work happens after these steps and belongs to the SDK track.
|
|
133
|
+
|
|
134
|
+
## Checklist
|
|
135
|
+
|
|
136
|
+
- Manifest is synced before submit.
|
|
137
|
+
- Create uses the existing manifest `workflowId`.
|
|
138
|
+
- Update lets the tool generate a fresh config UUID.
|
|
139
|
+
- Update has a concrete `updatePrompt`.
|
|
140
|
+
- The manifest is re-read after update.
|
|
141
|
+
- SDK bindings are copied from manifest, not from memory or old status IDs.
|