howone 0.1.15 → 0.1.17
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-sdk/references/03-ai-actions.md +44 -2
- package/templates/vite/.howone/skills/howone-sdk/references/06-react-integration.md +3 -3
- package/templates/vite/package.json +1 -1
- package/templates/vite/src/App.tsx +1 -1
- package/templates/vite/src/lib/sdk.ts +1 -0
package/package.json
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# AI Actions
|
|
2
2
|
|
|
3
|
+
## Manifest Contract — Read This First
|
|
4
|
+
|
|
5
|
+
**`src/lib/sdk.ts` must be generated from `.howone/ai/manifest.json`. Do not write it from memory or from generic examples.**
|
|
6
|
+
|
|
7
|
+
For every capability in `manifest.json`:
|
|
8
|
+
1. Read `name`, `workflowId`, `inputSchema`, `outputSchema`
|
|
9
|
+
2. Generate a zod schema from `inputSchema.properties`
|
|
10
|
+
3. Call `defineAiAction(name, { workflowId, inputSchema })` — **`workflowId` is mandatory**
|
|
11
|
+
|
|
12
|
+
Without `workflowId`, the SDK falls back to using the action name as the URL segment. Action names are not UUIDs — the EAX server will reject the call with "invalid input syntax for type uuid".
|
|
13
|
+
|
|
14
|
+
## When to Write SDK Bindings
|
|
15
|
+
|
|
16
|
+
**Do NOT write `defineAiAction` until `.howone/ai/manifest.json` contains a confirmed `workflowId`.**
|
|
17
|
+
|
|
18
|
+
Correct sequence:
|
|
19
|
+
1. `ai_capability_design` — design the capability schema
|
|
20
|
+
2. `sync_ai_artifacts` — sync manifest to disk
|
|
21
|
+
3. `external_ai_capability` — submit workflow to EAX; returns confirmed `workflowId`
|
|
22
|
+
4. Confirmed `workflowId` is written back to the backend capability record
|
|
23
|
+
5. `sync_ai_artifacts` again — manifest now contains `workflowId`
|
|
24
|
+
6. Read `.howone/ai/manifest.json` → write `src/lib/sdk.ts` with `workflowId`
|
|
25
|
+
|
|
26
|
+
Building without errors does **not** mean the AI workflow binding is correct. A missing `workflowId` causes a runtime UUID error at the EAX execution call.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
3
30
|
## Core Concepts
|
|
4
31
|
|
|
5
32
|
- `defineAiAction(id, config)` declares a typed AI action from a workflow ID.
|
|
@@ -16,6 +43,7 @@
|
|
|
16
43
|
|
|
17
44
|
```ts
|
|
18
45
|
type AiActionConfig<TInput, TOutput> = {
|
|
46
|
+
workflowId: string // REQUIRED — UUID from manifest.json. Without this, SDK uses action name as URL segment (not a UUID → EAX rejects).
|
|
19
47
|
inputSchema?: z.ZodType<TInput> // validates input before calling the workflow
|
|
20
48
|
outputSchema?: z.ZodType<TOutput> // validates the full ExecutionResult envelope (see caution below)
|
|
21
49
|
mode?: 'run' | 'stream' | 'events' // default: supports all three modes
|
|
@@ -69,12 +97,13 @@ type AiEvent = {
|
|
|
69
97
|
|
|
70
98
|
## Defining AI Actions
|
|
71
99
|
|
|
72
|
-
### Basic action —
|
|
100
|
+
### Basic action — always include workflowId from manifest.json
|
|
73
101
|
|
|
74
102
|
```ts
|
|
75
103
|
import { defineAiAction, defineAiActions } from '@howone/sdk'
|
|
76
104
|
import { z } from 'zod'
|
|
77
105
|
|
|
106
|
+
// Source: .howone/ai/manifest.json → capabilities[0].inputSchema.properties
|
|
78
107
|
export const generateStoryInputSchema = z.object({
|
|
79
108
|
topic: z.string().min(1),
|
|
80
109
|
ageRange: z.enum(['3-5', '6-8', '9-12']),
|
|
@@ -82,8 +111,10 @@ export const generateStoryInputSchema = z.object({
|
|
|
82
111
|
})
|
|
83
112
|
export type GenerateStoryInput = z.infer<typeof generateStoryInputSchema>
|
|
84
113
|
|
|
114
|
+
// workflowId from .howone/ai/manifest.json → capabilities[0].workflowId
|
|
85
115
|
export const ai = defineAiActions({
|
|
86
116
|
generateStory: defineAiAction('generateStory', {
|
|
117
|
+
workflowId: 'd69ab648-2c00-4d94-928e-01bd7b2a5bb2', // ← from manifest.json
|
|
87
118
|
inputSchema: generateStoryInputSchema,
|
|
88
119
|
}),
|
|
89
120
|
})
|
|
@@ -103,31 +134,39 @@ export type GenerateStoryOutput = z.infer<typeof generateStoryOutputSchema>
|
|
|
103
134
|
// AiResult envelope. Instead, cast finalResult after run():
|
|
104
135
|
export const ai = defineAiActions({
|
|
105
136
|
generateStory: defineAiAction('generateStory', {
|
|
137
|
+
workflowId: 'd69ab648-2c00-4d94-928e-01bd7b2a5bb2', // ← from manifest.json
|
|
106
138
|
inputSchema: generateStoryInputSchema,
|
|
107
139
|
// outputSchema: omit — cast manually
|
|
108
140
|
}),
|
|
109
141
|
})
|
|
110
142
|
```
|
|
111
143
|
|
|
112
|
-
### Multiple actions
|
|
144
|
+
### Multiple actions — each must have its own workflowId from manifest.json
|
|
113
145
|
|
|
114
146
|
```ts
|
|
147
|
+
// Each workflowId is the UUID from .howone/ai/manifest.json for that capability
|
|
115
148
|
export const ai = defineAiActions({
|
|
116
149
|
generateStory: defineAiAction('generateStory', {
|
|
150
|
+
workflowId: 'd69ab648-2c00-4d94-928e-01bd7b2a5bb2',
|
|
117
151
|
inputSchema: z.object({ topic: z.string(), language: z.string() }),
|
|
118
152
|
}),
|
|
119
153
|
translateText: defineAiAction('translateText', {
|
|
154
|
+
workflowId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
|
|
120
155
|
inputSchema: z.object({ text: z.string(), targetLang: z.string() }),
|
|
121
156
|
}),
|
|
122
157
|
summarizeArticle: defineAiAction('summarizeArticle', {
|
|
158
|
+
workflowId: 'f9e8d7c6-b5a4-3210-fedc-ba9876543210',
|
|
123
159
|
inputSchema: z.object({ url: z.string().url(), maxWords: z.number().int().optional() }),
|
|
124
160
|
}),
|
|
125
161
|
analyzeImage: defineAiAction('analyzeImage', {
|
|
162
|
+
workflowId: '11223344-5566-7788-99aa-bbccddeeff00',
|
|
126
163
|
inputSchema: z.object({ imageUrl: z.string().url(), prompt: z.string().optional() }),
|
|
127
164
|
}),
|
|
128
165
|
})
|
|
129
166
|
```
|
|
130
167
|
|
|
168
|
+
> **Note**: The UUIDs above are placeholders. Always copy the exact value from `.howone/ai/manifest.json`.
|
|
169
|
+
|
|
131
170
|
---
|
|
132
171
|
|
|
133
172
|
## Calling AI Actions
|
|
@@ -482,6 +521,9 @@ function StreamingStoryGenerator({ input }: { input: GenerateStoryInput }) {
|
|
|
482
521
|
|
|
483
522
|
| Mistake | Correct Pattern |
|
|
484
523
|
|---|---|
|
|
524
|
+
| `defineAiAction('generateStory', { inputSchema })` — no `workflowId` | Always include `workflowId` from `manifest.json`; SDK falls back to action name, which is not a UUID → EAX rejects |
|
|
525
|
+
| Writing `src/lib/sdk.ts` before `sync_ai_artifacts` has a confirmed `workflowId` | Run `external_ai_capability` → `sync_ai_artifacts` first; only write bindings after manifest has `workflowId` |
|
|
526
|
+
| Hardcoding `workflowId` from memory or guessing | Always read from `.howone/ai/manifest.json` — copy the exact UUID |
|
|
485
527
|
| `howone.ai.run.generateStory(input)` | `howone.ai.generateStory.run(input)` |
|
|
486
528
|
| Action named `run`, `stream`, or `events` | Rename to e.g. `executeWorkflow`, `streamContent` |
|
|
487
529
|
| `outputSchema: z.object({ title: z.string() })` expecting `finalResult` shape | Omit `outputSchema`; cast `result.finalResult` manually |
|
|
@@ -42,7 +42,7 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
|
42
42
|
<React.StrictMode>
|
|
43
43
|
<HowOneProvider
|
|
44
44
|
projectId={import.meta.env.VITE_HOWONE_PROJECT_ID}
|
|
45
|
-
auth="
|
|
45
|
+
auth="required"
|
|
46
46
|
brand="visible"
|
|
47
47
|
theme="system"
|
|
48
48
|
>
|
|
@@ -101,7 +101,7 @@ interface HowOneProviderProps {
|
|
|
101
101
|
</HowOneProvider>
|
|
102
102
|
|
|
103
103
|
// Dark mode forced
|
|
104
|
-
<HowOneProvider auth="
|
|
104
|
+
<HowOneProvider auth="required" theme="dark" forceTheme>
|
|
105
105
|
<App />
|
|
106
106
|
</HowOneProvider>
|
|
107
107
|
```
|
|
@@ -331,7 +331,7 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
|
331
331
|
<React.StrictMode>
|
|
332
332
|
<HowOneProvider
|
|
333
333
|
projectId={import.meta.env.VITE_HOWONE_PROJECT_ID}
|
|
334
|
-
auth="
|
|
334
|
+
auth="required"
|
|
335
335
|
theme="system"
|
|
336
336
|
brand="visible"
|
|
337
337
|
>
|
|
@@ -19,6 +19,7 @@ export const entities = defineEntities({
|
|
|
19
19
|
export const ai = defineAiActions({
|
|
20
20
|
// Add generated AI action bindings here, for example:
|
|
21
21
|
// generateImage: defineAiAction("generateImage", {
|
|
22
|
+
// workflowId: "<workflow-uuid>", // workflow ID for this capability
|
|
22
23
|
// inputSchema: generateImageInputSchema,
|
|
23
24
|
// outputSchema: generateImageOutputSchema,
|
|
24
25
|
// }),
|