@mindstudio-ai/remy 0.1.249 → 0.1.250
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/dist/prompt/compiled/agent-interfaces.md +2 -0
- package/dist/prompt/compiled/sdk-actions.md +1 -1
- package/dist/prompt/compiled/task-agents.md +40 -9
- package/dist/prompt/static/coding.md +1 -1
- package/dist/prompt/static/intake.md +1 -1
- package/dist/subagents/codeSanityCheck/prompt.md +9 -1
- package/package.json +1 -1
|
@@ -30,6 +30,8 @@ The system prompt says *who* the agent is. The tool descriptions say *what it ca
|
|
|
30
30
|
- **Parameter guidance** beyond the schema — what makes a good value, when to include optional fields, what to skip
|
|
31
31
|
- **Return value** and how to present results to the user
|
|
32
32
|
|
|
33
|
+
Note: Task agents (`runTask`) can also expose app methods as tools, but their descriptions are written **inline at the call site**, not compiled here. The two are deliberately different: an agent interface is one long-lived persona whose tools are a stable capability surface, so each method earns one carefully-written description in `tools/*.md`. A task agent is narrow and single-purpose, and the same method gets framed differently depending on the job — so its description belongs with the task, not the method.
|
|
34
|
+
|
|
33
35
|
### Not every method should be a tool
|
|
34
36
|
|
|
35
37
|
Expose methods that serve the conversational flow. Internal helpers, admin-only methods, and batch operations often don't belong in the agent's toolset. A focused set of well-described tools performs better than many underdocumented ones.
|
|
@@ -154,4 +154,4 @@ Consider the ways in which AI can be incorporated into backend methods to solve
|
|
|
154
154
|
|
|
155
155
|
### Task Agents
|
|
156
156
|
|
|
157
|
-
For multi-step tasks where the model needs to autonomously compose actions (research + scrape + generate, enrichment pipelines, content creation), use `runTask()` instead of chaining actions manually. It runs an agent loop
|
|
157
|
+
For multi-step tasks where the model needs to autonomously compose actions (research + scrape + generate, enrichment pipelines, content creation), use `runTask()` instead of chaining actions manually. It runs an agent loop and returns structured JSON. Its tools can include SDK actions as well as your app's own methods, so the agent can read your data to decide what to do next and write results back itself. See the task agents reference for full details.
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
A user types the name of a restaurant into your app, or uploads a photo of a storefront. The API call returns early, and in the background, a task agent searches Google, finds the official website, scrapes the address, gets the official social media accounts, and generates a stylized watercolor postcard of the exterior from images it found online. The user gets back a rich, illustrated card with the canonical name, website, address, and a custom image. A few tool calls (some in parallel), fully autonomous.
|
|
4
4
|
|
|
5
|
-
`runTask()` makes this possible. It runs a multi-step, tool-use agent loop: give it a prompt, a set of
|
|
5
|
+
`runTask()` makes this possible. It runs a multi-step, tool-use agent loop: give it a prompt, a set of tools, and an example of the structured output you want. The platform runs the loop (calling the model, executing tool calls, feeding results back) until the model produces JSON matching your output example. The model decides what to do next based on intermediate results — retrying searches with different terms, working around failed tools, batching independent calls in parallel.
|
|
6
|
+
|
|
7
|
+
Tools are **SDK actions** (`searchGoogle`, `generateImage`, …) and **your own app's methods** (`{ appMethod: 'saveVendor' }`), in any combination. That second half is what makes a task agent part of your app rather than a detached research bot: it can read your tables to decide what to do next, and write results back itself instead of handing them to you to persist.
|
|
6
8
|
|
|
7
9
|
This is one of the most powerful pieces of the MindStudio SDK and can make turn apps from amazing into truly magical. Use `askMindStudioSdk` to help construct the perfect agent for a task.
|
|
8
10
|
|
|
@@ -16,10 +18,12 @@ Run tasks in the background — depending on complexity they can take time to co
|
|
|
16
18
|
- **Content creation pipelines:** "Write SEO copy for this product in 3 languages, generate a hero image, extract keywords" — the model calls text generation, image generation, and analysis actions as needed.
|
|
17
19
|
- **Data processing with judgment:** "Given this restaurant name, find the canonical name, website, address, and create a stylized illustration" — the model searches, verifies, generates, and returns clean structured output.
|
|
18
20
|
- **Any multi-step task with branching logic:** If the model might need to retry a search with different terms, try a different approach when one fails, or make decisions based on intermediate results.
|
|
21
|
+
- **Work that depends on app state:** "Check which vendors are missing contact details, research those, and update them" — the agent reads your data with one method, decides what needs doing, and writes back with another.
|
|
19
22
|
|
|
20
23
|
## When NOT to Use
|
|
21
24
|
|
|
22
|
-
- **Simple linear pipelines (2-3 steps, no branching):** Just call the SDK actions directly in sequence. `runTask()` adds overhead from the model reasoning about what to do next.
|
|
25
|
+
- **Simple linear pipelines (2-3 steps, no branching):** Just call the SDK actions or your methods directly in sequence. `runTask()` adds overhead from the model reasoning about what to do next.
|
|
26
|
+
- **Anything with a deterministic answer:** If you know exactly which methods to call and in what order, call them. Handing a fixed sequence to a model buys nothing and can go wrong.
|
|
23
27
|
- **Chat/conversation:** Use an Agent interface instead. Task agents are single-shot, no persistent conversation history.
|
|
24
28
|
- **One-off text generation:** Just use `generateText()` directly.
|
|
25
29
|
|
|
@@ -36,7 +40,8 @@ const result = await mindstudio.runTask<{
|
|
|
36
40
|
}>({
|
|
37
41
|
prompt: `You are a restaurant research assistant. Given a restaurant name,
|
|
38
42
|
find its canonical name, website URL, full address, and create a stylized
|
|
39
|
-
watercolor illustration of the restaurant exterior
|
|
43
|
+
watercolor illustration of the restaurant exterior. Save the result before
|
|
44
|
+
you finish.`,
|
|
40
45
|
|
|
41
46
|
input: { restaurantName: 'Tartine Bakery SF' },
|
|
42
47
|
|
|
@@ -44,6 +49,10 @@ const result = await mindstudio.runTask<{
|
|
|
44
49
|
'searchGoogle',
|
|
45
50
|
'fetchUrl',
|
|
46
51
|
{ method: 'generateImage', defaults: { imageModelOverride: { model: 'seedream-4.5' } } },
|
|
52
|
+
{
|
|
53
|
+
appMethod: 'saveRestaurant',
|
|
54
|
+
description: 'Persist a researched restaurant. Call once, at the end, when you have the canonical name, address and illustration.',
|
|
55
|
+
},
|
|
47
56
|
],
|
|
48
57
|
|
|
49
58
|
structuredOutputExample: {
|
|
@@ -85,24 +94,45 @@ await Table.update(id, result.output);
|
|
|
85
94
|
|
|
86
95
|
## Tool Configuration
|
|
87
96
|
|
|
88
|
-
|
|
97
|
+
The model gets the full input schema for each tool so it knows what parameters to pass. Only include tools the task actually needs — the model may use extra tools unnecessarily.
|
|
89
98
|
|
|
90
99
|
Use tool defaults for model/config choices. Use the prompt for task-level instructions.
|
|
91
100
|
|
|
92
101
|
```typescript
|
|
93
102
|
tools: [
|
|
94
|
-
//
|
|
103
|
+
// SDK action — just the action name
|
|
95
104
|
'searchGoogle',
|
|
96
105
|
'fetchUrl',
|
|
97
106
|
'scrapeUrl',
|
|
98
107
|
|
|
99
|
-
//
|
|
108
|
+
// SDK action with defaults — override specific input fields while letting the model control the rest
|
|
100
109
|
{ method: 'generateImage', defaults: { imageModelOverride: { model: 'seedream-4.5' } } },
|
|
101
110
|
{ method: 'analyzeImage', defaults: { visionModelOverride: { model: 'gemini-3-flash' } } },
|
|
111
|
+
|
|
112
|
+
// One of your app's own methods — note `appMethod`, not `method`
|
|
113
|
+
{ appMethod: 'listVendorsMissingContacts', description: 'Vendors with no email on file. Call this first to decide what needs researching.' },
|
|
114
|
+
{ appMethod: 'updateVendor', description: 'Write researched contact details back. One call per vendor.' },
|
|
102
115
|
]
|
|
103
116
|
```
|
|
104
117
|
|
|
105
|
-
When the model calls a tool, the platform deep-merges the model's arguments
|
|
118
|
+
When the model calls a tool, the platform deep-merges your defaults over the model's arguments. **Defaults win** — any field set in `defaults` overrides whatever the model passed for it, including nested fields, so the model can't talk its way out of a pinned model or config. The model decides what to do (prompt, query, parameters), you control which model/config it uses. If the model needs to search and generate an image and those are independent, it will call both tools in the same turn (parallel execution server-side).
|
|
119
|
+
|
|
120
|
+
### App methods as tools
|
|
121
|
+
|
|
122
|
+
`{ appMethod: 'methodId' }` exposes one of your app's methods. Use `appMethod`, not `method` — `method` means an SDK action, and the two are different namespaces.
|
|
123
|
+
|
|
124
|
+
**Write the description.** Unlike agent interfaces, where each method gets one compiled description, a task agent's tool descriptions are written inline, per task. This is deliberate: the same method serves different purposes in different tasks. `getVendor` called by an enrichment task and `getVendor` called by a reporting task want different framing — when to call it, what to do with the result, whether to call it once or per item. The method's own description is only a fallback.
|
|
125
|
+
|
|
126
|
+
Keep them short and task-specific. Say when to reach for it and when not to, since the model is choosing from a small flat list.
|
|
127
|
+
|
|
128
|
+
**Authorization is automatic.** The method runs as the user who invoked the method that started the task, with their roles. A method gated on a role they lack is rejected at runtime, exactly as if they'd called it themselves. The agent cannot reach anything the user couldn't — but that also means a task started from a background context (cron, webhook) runs with the `system` role, so gate accordingly.
|
|
129
|
+
|
|
130
|
+
**Constraints worth knowing:**
|
|
131
|
+
|
|
132
|
+
- A method invoked as a task tool **cannot start another task agent**. Decompose differently if you're reaching for that.
|
|
133
|
+
- A method id that collides with an SDK action name is rejected — the model sees one flat tool namespace. Rename the method.
|
|
134
|
+
- Method calls run in parallel with everything else in the turn, so don't expose two methods that would conflict if called simultaneously.
|
|
135
|
+
- Cost from inside a method (its own model calls) doesn't appear in the task's `usage.totalBillingCost`. It's billed and attributed to that method, just not rolled into the task total.
|
|
106
136
|
|
|
107
137
|
## Voice & Tone in Prompts
|
|
108
138
|
|
|
@@ -114,10 +144,10 @@ When a task agent produces user-facing text, the prompt must include a note voic
|
|
|
114
144
|
|-------|----------|---------|-------------|
|
|
115
145
|
| `prompt` | Yes | — | System prompt defining the agent's behavior |
|
|
116
146
|
| `input` | Yes | — | Structured input (passed as user message) |
|
|
117
|
-
| `tools` | Yes | — | SDK action names with optional defaults |
|
|
147
|
+
| `tools` | Yes | — | SDK action names and/or `{ appMethod, description }` entries, each with optional `defaults` |
|
|
118
148
|
| `structuredOutputExample` | Yes | — | Object or JSON string showing expected output shape. Use realistic example values, not placeholders like `'string'` |
|
|
119
149
|
| `model` | Yes | — | Model ID (must support tool use) |
|
|
120
|
-
| `maxTurns` | No |
|
|
150
|
+
| `maxTurns` | No | 20 | Max loop iterations (capped at 100) |
|
|
121
151
|
| `onEvent` | No | — | SSE event callback for real-time streaming |
|
|
122
152
|
|
|
123
153
|
## Models
|
|
@@ -170,6 +200,7 @@ Without `onEvent`, the SDK uses async polling (returns silently when complete).
|
|
|
170
200
|
|
|
171
201
|
- Model produces non-JSON output: retried automatically if turns remain
|
|
172
202
|
- Tool execution fails: error fed back to model, it can retry or work around it
|
|
203
|
+
- An app method that throws: its actual error message goes back to the model, so a `MindStudioError` you throw deliberately ("vendor not found", "missing required field") is usable guidance the agent can act on. Worth throwing informative errors in methods you expose as tools
|
|
173
204
|
- Max turns exceeded: one final forced output attempt with tools disabled
|
|
174
205
|
- If output still can't be parsed: `parsedSuccessfully` will be `false`, raw text available in `outputRaw`
|
|
175
206
|
|
|
@@ -28,7 +28,7 @@ Process logs are available at .logs/ in NDJSON format (one JSON object per line)
|
|
|
28
28
|
### MindStudio SDK
|
|
29
29
|
For any work involving AI models, external actions (web scraping, email, SMS), or third-party API/OAuth connections, prefer the `@mindstudio-ai/agent` SDK. It removes the need to research API methods, configure keys and tokens, or require the user to set up developer accounts.
|
|
30
30
|
|
|
31
|
-
For multi-step tasks with branching logic (research, enrichment, content pipelines), use `runTask()` instead of manually chaining SDK actions. It runs an autonomous agent loop that composes
|
|
31
|
+
For multi-step tasks with branching logic (research, enrichment, content pipelines), use `runTask()` instead of manually chaining SDK actions. It runs an autonomous agent loop that composes tools, retries on failure, and returns structured JSON. Tools are SDK actions and your own app methods — the agent can read app state to decide what to do next and persist results itself. See the task agents reference for details.
|
|
32
32
|
|
|
33
33
|
For methods that take more than a few seconds, use `stream()` from `@mindstudio-ai/agent` to push real-time progress to the frontend. Pipe `onLog` from SDK actions through `stream()` so users see what's happening. The frontend calls the method with `stream: true` and gets updates via `onToken`. See the methods reference for the full pattern.
|
|
34
34
|
|
|
@@ -10,7 +10,7 @@ Remy apps are full-stack TypeScript projects. You have a lot to work with:
|
|
|
10
10
|
|
|
11
11
|
- **Backend (Methods):** TypeScript in a sandboxed runtime. Any npm package. Managed SQLite database with typed schemas and automatic migrations. Built-in app-managed auth with email/SMS verification, cookie sessions, and role enforcement. None of these are required — use what the app needs.
|
|
12
12
|
- **Frontend (Web Interface):** Starts as Vite + React, but any TypeScript project with a build command works. Any framework, any library, or no framework at all.
|
|
13
|
-
- **AI & integrations:** The `@mindstudio-ai/agent` SDK gives access to 200+ AI models (OpenAI, Anthropic, Google, Meta, Mistral, and more) and 1000+ integrations (email, SMS, Slack, HubSpot, Google Workspace, web scraping, image/video generation, media processing) with zero configuration — credentials are handled automatically. No API keys needed. Beyond individual actions, `runTask()` lets you spin up lightweight autonomous task agents that chain these actions together with judgment — e.g., a user types a restaurant name and the backend autonomously researches it in the background, finds the address,
|
|
13
|
+
- **AI & integrations:** The `@mindstudio-ai/agent` SDK gives access to 200+ AI models (OpenAI, Anthropic, Google, Meta, Mistral, and more) and 1000+ integrations (email, SMS, Slack, HubSpot, Google Workspace, web scraping, image/video generation, media processing) with zero configuration — credentials are handled automatically. No API keys needed. Beyond individual actions, `runTask()` lets you spin up lightweight autonomous task agents that chain these actions together with judgment — e.g., a user types a restaurant name and the backend autonomously researches it in the background, finds the address, generates a custom illustration, and saves the finished record itself. These agents can call the app's own methods too, so they can read existing data to decide what needs doing and write results straight back. Think about where this kind of enrichment would make a feature go from functional to magical.
|
|
14
14
|
- **Interfaces:** Web UI, REST API, cron jobs, webhooks, MCP tool servers, email processors, conversational AI agents — all backed by the same methods. An app can use any combination.
|
|
15
15
|
|
|
16
16
|
This is a capable, stable platform. Build with confidence; you're building production-grade apps, not fragile prototypes.
|
|
@@ -65,7 +65,15 @@ When a plan includes multiple screens/API calls, always note this item for the d
|
|
|
65
65
|
|
|
66
66
|
- **Auth state read once instead of subscribed.** If the plan reads `auth.currentUser` or `auth.getCurrentUser()` in a `useState` initializer, at component top-level, or in a one-time check, the UI won't update after login/logout. The correct pattern is `auth.onAuthStateChanged(cb)` which fires immediately and on every auth transition. Flag if you see auth state read without a subscription.
|
|
67
67
|
|
|
68
|
-
- **Manual multi-step
|
|
68
|
+
- **Manual multi-step chains that should be `runTask()`.** If a method chains AI-driven work with branching logic (search, then scrape based on results, then generate based on what was scraped), that's a `runTask()` use case. `runTask()` runs an agent loop that autonomously calls tools and returns structured JSON. The developer writes a prompt and an output example instead of imperative code. Flag when you see methods with complex sequential/branching chains — especially research, enrichment, or content generation pipelines. Similarly, flag opportunities where the developer might not have realized they could get better and richer data via runTask - it's a really powerful lever for working with data (e.g., user provides some fragment and agent task goes off and enriches it) that the developer might not have remembered when planning their work.
|
|
69
|
+
|
|
70
|
+
Tools are SDK actions **and the app's own methods** (`{ appMethod: 'saveVendor', description: '...' }`), which widens this considerably. The pattern most worth looking for: work that needs to *read* app state to decide what to do next (fetch rows, loop, research each, update each) hand-rolled as a loop, when the agent could take a read method and a write method and exercise the judgment itself. App methods run as the invoking user with their roles, so authorization is unchanged.
|
|
71
|
+
|
|
72
|
+
Two things NOT to flag. A deterministic sequence that happens to touch several methods — if the order is known up front and no judgment is involved, imperative code is correct and cheaper. And the fire-and-forget background pattern, where a method kicks off `runTask()` and writes the result back in `.then()`: that write-back is doing status management around `parsedSuccessfully`, which the agent can't do for itself because it doesn't know when its own output is garbage. That one is the recommended pattern, not a smell.
|
|
73
|
+
|
|
74
|
+
- **Task agent tool descriptions missing or recycled.** When a plan exposes app methods to `runTask()`, each entry should carry an inline `description` written for *that* task — when to call it, when not to, what to do with the result. Falling back to the method's own description is allowed but usually too generic, and the description is the main thing determining whether the agent uses the tool correctly. Flag entries with no description, or the same description pasted across different tasks.
|
|
75
|
+
|
|
76
|
+
- **A method exposed as a task tool that itself calls `runTask()`.** Task agents can't nest — the inner call is rejected at runtime. Flag it and suggest flattening the decomposition.
|
|
69
77
|
|
|
70
78
|
- **MindStudio SDK `runTask()` output used without validation.** `runTask()` can return successfully with garbage output (null fields, echoed input, raw text). The result includes `parsedSuccessfully` — if the plan uses `result.output` without checking `result.parsedSuccessfully` first, flag it. This is the #1 footgun with task agents.
|
|
71
79
|
|