@mindstudio-ai/remy 0.1.0
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/README.md +314 -0
- package/dist/actions/publish.md +12 -0
- package/dist/actions/sync.md +19 -0
- package/dist/compiled/README.md +100 -0
- package/dist/compiled/auth.md +77 -0
- package/dist/compiled/design.md +173 -0
- package/dist/compiled/dev-and-deploy.md +69 -0
- package/dist/compiled/interfaces.md +238 -0
- package/dist/compiled/manifest.md +107 -0
- package/dist/compiled/media-cdn.md +51 -0
- package/dist/compiled/methods.md +225 -0
- package/dist/compiled/msfm.md +133 -0
- package/dist/compiled/platform.md +101 -0
- package/dist/compiled/scenarios.md +103 -0
- package/dist/compiled/sdk-actions.md +152 -0
- package/dist/compiled/tables.md +192 -0
- package/dist/headless.d.ts +16 -0
- package/dist/headless.js +2515 -0
- package/dist/index.js +3164 -0
- package/dist/static/authoring.md +53 -0
- package/dist/static/identity.md +1 -0
- package/dist/static/instructions.md +21 -0
- package/dist/static/intake.md +44 -0
- package/dist/static/lsp.md +4 -0
- package/dist/static/projectContext.ts +155 -0
- package/package.json +52 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# MindStudio Agent SDK
|
|
2
|
+
|
|
3
|
+
`@mindstudio-ai/agent` provides access to 200+ AI models and 1,000+ actions through a single API key. No separate provider keys needed — MindStudio routes to the correct provider (OpenAI, Anthropic, Google, etc.) server-side.
|
|
4
|
+
|
|
5
|
+
**Full reference:** For complete method signatures, parameters, and output types, read `dist/methods/node_modules/@mindstudio-ai/agent/llms.txt`. This file ships with the package and contains the full API reference for all 170+ actions.
|
|
6
|
+
|
|
7
|
+
## Usage in Methods
|
|
8
|
+
|
|
9
|
+
Inside a MindStudio app method, create an instance with no arguments — credentials come from the execution environment:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { MindStudioAgent } from '@mindstudio-ai/agent';
|
|
13
|
+
|
|
14
|
+
const agent = new MindStudioAgent();
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Every action is a method on the agent instance:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
const { content } = await agent.generateText({ message: 'Summarize this...' });
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Results are returned flat — output fields at the top level alongside metadata:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
const result = await agent.generateText({ message: 'Hello' });
|
|
27
|
+
result.content; // step-specific output
|
|
28
|
+
result.$billingCost; // cost in credits (if applicable)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Available Actions
|
|
32
|
+
|
|
33
|
+
### AI Generation
|
|
34
|
+
|
|
35
|
+
| Action | What it does | Key input | Key output |
|
|
36
|
+
|--------|-------------|-----------|------------|
|
|
37
|
+
| `generateText` | Text generation with any LLM | `message`, `modelOverride?` | `content` |
|
|
38
|
+
| `generateImage` | Image from text prompt | `prompt`, `modelOverride?` | `imageUrl` |
|
|
39
|
+
| `generateVideo` | Video from text/image | `prompt`, `imageUrl?` | `videoUrl` |
|
|
40
|
+
| `textToSpeech` | Text to spoken audio | `text`, `modelOverride?` | `audioUrl` |
|
|
41
|
+
| `generateMusic` | Music from text description | `prompt` | `audioUrl` |
|
|
42
|
+
| `generateLipsync` | Animate face to match audio | `imageUrl`, `audioUrl` | `videoUrl` |
|
|
43
|
+
| `generateAsset` | HTML/PDF/PNG/video output | `prompt` | `assetUrl` |
|
|
44
|
+
| `generateChart` | Chart from data | `data`, `chartType` | `imageUrl` |
|
|
45
|
+
|
|
46
|
+
### AI Analysis
|
|
47
|
+
|
|
48
|
+
| Action | What it does | Key input | Key output |
|
|
49
|
+
|--------|-------------|-----------|------------|
|
|
50
|
+
| `analyzeImage` | Vision model analysis | `prompt`, `imageUrl` | `analysis` |
|
|
51
|
+
| `analyzeVideo` | Video analysis | `prompt`, `videoUrl` | `analysis` |
|
|
52
|
+
| `transcribeAudio` | Audio to text | `audioUrl` | `transcription` |
|
|
53
|
+
| `extractText` | Extract text from documents/images | `url` | `text` |
|
|
54
|
+
| `detectPII` | Find personal data | `text` | `entities` |
|
|
55
|
+
|
|
56
|
+
### Web & Search
|
|
57
|
+
|
|
58
|
+
| Action | What it does | Key input | Key output |
|
|
59
|
+
|--------|-------------|-----------|------------|
|
|
60
|
+
| `scrapeUrl` | Extract page content | `url` | `markdown` |
|
|
61
|
+
| `searchGoogle` | Google search | `query` | `results` |
|
|
62
|
+
| `searchGoogleImages` | Image search | `query` | `results` |
|
|
63
|
+
| `searchGoogleNews` | News search | `query` | `results` |
|
|
64
|
+
| `searchPerplexity` | AI-powered search | `query` | `answer` |
|
|
65
|
+
| `httpRequest` | Custom HTTP call | `url`, `method`, `headers?`, `body?` | `response` |
|
|
66
|
+
|
|
67
|
+
### Communication
|
|
68
|
+
|
|
69
|
+
| Action | What it does | Key input | Key output |
|
|
70
|
+
|--------|-------------|-----------|------------|
|
|
71
|
+
| `sendEmail` | Send an email | `to`, `subject`, `body` | `messageId` |
|
|
72
|
+
| `sendSMS` | Send a text message | `to`, `message` | `messageId` |
|
|
73
|
+
| `postToSlackChannel` | Post to Slack | `channel`, `message` | — |
|
|
74
|
+
|
|
75
|
+
### Media Processing
|
|
76
|
+
|
|
77
|
+
| Action | What it does |
|
|
78
|
+
|--------|-------------|
|
|
79
|
+
| `removeBackgroundFromImage` | Remove image background |
|
|
80
|
+
| `upscaleImage` | Upscale image resolution |
|
|
81
|
+
| `imageFaceSwap` | Swap faces in an image |
|
|
82
|
+
| `imageRemoveWatermark` | Remove watermarks |
|
|
83
|
+
| `mergeVideos` | Concatenate video clips |
|
|
84
|
+
| `trimMedia` | Trim audio/video |
|
|
85
|
+
| `addSubtitlesToVideo` | Auto-generate subtitles |
|
|
86
|
+
| `extractAudioFromVideo` | Extract audio track |
|
|
87
|
+
| `captureThumbnail` | Get video thumbnail |
|
|
88
|
+
|
|
89
|
+
### Files & Data
|
|
90
|
+
|
|
91
|
+
| Action | What it does |
|
|
92
|
+
|--------|-------------|
|
|
93
|
+
| `uploadFile` | Upload a file to CDN |
|
|
94
|
+
| `downloadVideo` | Download a video URL |
|
|
95
|
+
| `getMediaMetadata` | Get dimensions, duration, etc. |
|
|
96
|
+
| `convertPdfToImages` | PDF pages to PNG images |
|
|
97
|
+
|
|
98
|
+
### Third-Party Integrations (OAuth Connectors)
|
|
99
|
+
|
|
100
|
+
850+ additional actions from the MindStudio Connector Registry, covering services like HubSpot, Salesforce, Airtable, Google Workspace, Notion, Coda, and many more. These require OAuth connections set up by the user in MindStudio.
|
|
101
|
+
|
|
102
|
+
Built-in connector methods include: ActiveCampaign, Airtable, Apollo, Coda, Facebook, Gmail, Google Docs/Sheets/Calendar/Drive, HubSpot, Hunter.io, Instagram, LinkedIn, Notion, X (Twitter), YouTube.
|
|
103
|
+
|
|
104
|
+
For other services, use `runFromConnectorRegistry`:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// Discover available connectors
|
|
108
|
+
const { connectors } = await agent.listConnectors();
|
|
109
|
+
|
|
110
|
+
// Get action details
|
|
111
|
+
const action = await agent.getConnectorAction('hubspot', 'create-contact');
|
|
112
|
+
|
|
113
|
+
// Execute
|
|
114
|
+
const result = await agent.runFromConnectorRegistry({
|
|
115
|
+
serviceId: 'hubspot',
|
|
116
|
+
actionId: 'create-contact',
|
|
117
|
+
input: { email: 'user@example.com', firstName: 'Alice' },
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Model Selection
|
|
122
|
+
|
|
123
|
+
Override the default model for any AI action:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
const { content } = await agent.generateText({
|
|
127
|
+
message: 'Hello',
|
|
128
|
+
modelOverride: {
|
|
129
|
+
model: 'claude-sonnet-4-6',
|
|
130
|
+
temperature: 0.7,
|
|
131
|
+
maxResponseTokens: 1024,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Browse available models:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const { models } = await agent.listModelsSummaryByType('llm_chat');
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Batch Execution
|
|
143
|
+
|
|
144
|
+
Run up to 50 actions in parallel:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
const result = await agent.executeStepBatch([
|
|
148
|
+
{ stepType: 'generateImage', step: { prompt: 'a sunset' } },
|
|
149
|
+
{ stepType: 'textToSpeech', step: { text: 'hello world' } },
|
|
150
|
+
]);
|
|
151
|
+
// result.results[0].output, result.results[1].output
|
|
152
|
+
```
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Tables & Database
|
|
2
|
+
|
|
3
|
+
## Defining a Table
|
|
4
|
+
|
|
5
|
+
One file per table in `dist/methods/src/tables/`. Each table is a `defineTable<T>()` call with a typed interface. Table names must match `[a-zA-Z0-9_]` only (no hyphens, spaces, or special characters). Use `snake_case` for table names (e.g., `purchase_orders`, not `purchase-orders`).
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { db } from '@mindstudio-ai/agent';
|
|
9
|
+
|
|
10
|
+
interface Vendor {
|
|
11
|
+
name: string;
|
|
12
|
+
contactEmail: string;
|
|
13
|
+
status: 'pending' | 'approved' | 'rejected';
|
|
14
|
+
taxId: string;
|
|
15
|
+
paymentTerms?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const Vendors = db.defineTable<Vendor>('vendors');
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
One export per file. The export name is referenced in `mindstudio.json` and imported in methods. Only define your own columns in the interface — do not add `id`, `created_at`, `updated_at`, or `last_updated_by` (they're provided automatically, see below).
|
|
22
|
+
|
|
23
|
+
### Column Types
|
|
24
|
+
|
|
25
|
+
| TypeScript type | SQLite type | Notes |
|
|
26
|
+
|----------------|-------------|-------|
|
|
27
|
+
| `string` | TEXT | Default for most fields |
|
|
28
|
+
| `number` | REAL | Numeric values |
|
|
29
|
+
| `boolean` | INTEGER | Stored as 0/1 |
|
|
30
|
+
| `object` / `array` / JSON types | TEXT | Stored as JSON string, parsed on read |
|
|
31
|
+
| `User` (branded type) | TEXT | User ID with `@@user@@` prefix (transparent — your code works with clean UUIDs) |
|
|
32
|
+
|
|
33
|
+
### System Columns
|
|
34
|
+
|
|
35
|
+
Every table automatically has these columns. The SDK adds them to the TypeScript return type automatically — you can access them on any row returned from `get()`, `filter()`, `push()`, etc. without declaring them in your interface. They're also stripped from write inputs, so you never pass them to `push()` or `update()`.
|
|
36
|
+
|
|
37
|
+
| Column | Type | Behavior |
|
|
38
|
+
|--------|------|----------|
|
|
39
|
+
| `id` | `string` (UUID) | Auto-generated on insert if not provided |
|
|
40
|
+
| `created_at` | `number` (unix ms) | Set on insert, never changes |
|
|
41
|
+
| `updated_at` | `number` (unix ms) | Updated on every write |
|
|
42
|
+
| `last_updated_by` | `string` | Set from the current user's auth context |
|
|
43
|
+
|
|
44
|
+
These are always available on read results:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
const vendor = await Vendors.get('some-id');
|
|
48
|
+
vendor.id; // string — always present
|
|
49
|
+
vendor.created_at; // number — unix ms
|
|
50
|
+
vendor.name; // string — your field
|
|
51
|
+
|
|
52
|
+
// Sort/filter by system columns works too
|
|
53
|
+
await Vendors.sortBy(v => v.created_at).reverse();
|
|
54
|
+
await Vendors.filter(v => v.id === someId);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## The `db` API
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { db } from '@mindstudio-ai/agent';
|
|
61
|
+
import { Vendors } from './tables/vendors';
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Creating Records
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// Single insert — returns the full row with id, created_at, etc.
|
|
68
|
+
const vendor = await Vendors.push({
|
|
69
|
+
name: 'Acme Corp',
|
|
70
|
+
contactEmail: 'billing@acme.com',
|
|
71
|
+
status: 'pending',
|
|
72
|
+
taxId: '12-3456789',
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Batch insert — returns array
|
|
76
|
+
const vendors = await Vendors.push([
|
|
77
|
+
{ name: 'Acme', status: 'pending', ... },
|
|
78
|
+
{ name: 'Globex', status: 'pending', ... },
|
|
79
|
+
]);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Reading Records
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
// By ID
|
|
86
|
+
const vendor = await Vendors.get('uuid-here'); // Vendor | null
|
|
87
|
+
|
|
88
|
+
// Find one matching a predicate
|
|
89
|
+
const first = await Vendors.findOne(v => v.status === 'approved');
|
|
90
|
+
|
|
91
|
+
// Filter — returns all matching rows
|
|
92
|
+
const approved = await Vendors.filter(v => v.status === 'approved');
|
|
93
|
+
|
|
94
|
+
// Chainable queries
|
|
95
|
+
const results = await Vendors
|
|
96
|
+
.filter(v => v.status === 'approved')
|
|
97
|
+
.sortBy(v => v.name)
|
|
98
|
+
.skip(10)
|
|
99
|
+
.take(5);
|
|
100
|
+
|
|
101
|
+
// Aggregates
|
|
102
|
+
const count = await Vendors.count();
|
|
103
|
+
const any = await Vendors.some(v => v.status === 'pending');
|
|
104
|
+
const all = await Vendors.every(v => v.status !== 'rejected');
|
|
105
|
+
const empty = await Vendors.isEmpty();
|
|
106
|
+
const cheapest = await Vendors.min(v => v.totalCents);
|
|
107
|
+
const grouped = await Vendors.groupBy(v => v.status);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Updating Records
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
// Update by ID — returns the updated row
|
|
114
|
+
const updated = await Vendors.update(vendor.id, {
|
|
115
|
+
status: 'approved',
|
|
116
|
+
});
|
|
117
|
+
// updated.updated_at is bumped automatically
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Deleting Records
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
await Vendors.remove(vendor.id); // by ID
|
|
124
|
+
const count = await Vendors.removeAll(v => v.status === 'rejected'); // by predicate
|
|
125
|
+
await Vendors.clear(); // delete all
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Filter Predicates
|
|
129
|
+
|
|
130
|
+
Predicates are arrow functions compiled to SQL WHERE clauses:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
Vendors.filter(v => v.status === 'approved') // equality
|
|
134
|
+
Vendors.filter(v => v.totalCents > 10000) // comparison
|
|
135
|
+
Vendors.filter(v => v.totalCents >= 5000 && v.totalCents <= 50000) // range
|
|
136
|
+
Vendors.filter(v => v.paymentTerms !== null) // null check
|
|
137
|
+
Vendors.filter(v => v.status === 'approved' && v.totalCents > 10000) // logical AND
|
|
138
|
+
Vendors.filter(v => v.status === 'approved' || v.status === 'pending') // logical OR
|
|
139
|
+
Vendors.filter(v => ['approved', 'pending'].includes(v.status)) // IN
|
|
140
|
+
Vendors.filter(v => v.name.includes('Acme')) // LIKE
|
|
141
|
+
Vendors.filter(v => v.address.city === 'New York') // nested JSON
|
|
142
|
+
const minAmount = 10000;
|
|
143
|
+
Vendors.filter(v => v.totalCents > minAmount) // captured variables
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
If a predicate can't be compiled to SQL (complex closures, function calls), the SDK falls back to fetching all rows and filtering in JavaScript. A warning is logged.
|
|
147
|
+
|
|
148
|
+
### Time Helpers
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
db.now() // current timestamp (unix ms)
|
|
152
|
+
db.days(n) // n days in ms
|
|
153
|
+
db.hours(n) // n hours in ms
|
|
154
|
+
db.minutes(n) // n minutes in ms
|
|
155
|
+
db.ago(duration) // now - duration
|
|
156
|
+
db.fromNow(duration) // now + duration
|
|
157
|
+
db.ago(db.days(7) + db.hours(12)) // composable — 7.5 days ago
|
|
158
|
+
|
|
159
|
+
// Use in queries
|
|
160
|
+
Invoices.filter(i => i.dueDate < db.ago(db.days(30)))
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Batch Queries
|
|
164
|
+
|
|
165
|
+
Execute multiple queries in a single round-trip:
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
const [vendors, orders] = await db.batch(
|
|
169
|
+
Vendors.filter(v => v.status === 'approved'),
|
|
170
|
+
PurchaseOrders.filter(po => po.vendorId === vendorId),
|
|
171
|
+
);
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Migrations
|
|
175
|
+
|
|
176
|
+
No migration files. Migrations are automatic:
|
|
177
|
+
- **New tables** — `CREATE TABLE` applied automatically
|
|
178
|
+
- **New columns** — `ALTER TABLE ADD COLUMN` applied automatically
|
|
179
|
+
- **Dropped columns** — `ALTER TABLE DROP COLUMN` applied automatically when a column is removed from the interface
|
|
180
|
+
- **Dropped tables** — `DROP TABLE` applied automatically when a table file is removed from the manifest
|
|
181
|
+
- **Type changes and renames** — not supported in the automatic migration path
|
|
182
|
+
|
|
183
|
+
On deploy, the platform:
|
|
184
|
+
1. Parses your table definition files (TypeScript AST — the interface IS the schema)
|
|
185
|
+
2. Diffs against the current live database schema
|
|
186
|
+
3. Generates DDL (`CREATE TABLE`, `ALTER TABLE ADD COLUMN`, `ALTER TABLE DROP COLUMN`, `DROP TABLE`)
|
|
187
|
+
4. Applies to a staging copy of the database
|
|
188
|
+
5. Promotes the staging copy to live
|
|
189
|
+
|
|
190
|
+
The TypeScript interface is the single source of truth for the schema. Add a field to the interface, push, and the column exists. No migration files, no CLI commands.
|
|
191
|
+
|
|
192
|
+
**In development**, schema changes are synced automatically to the dev database. The dev database is a disposable snapshot — it can be reset to a fresh copy of production data or truncated to empty tables at any time. There's no risk of breaking anything by experimenting with schema changes in dev.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Headless mode — stdin/stdout JSON protocol for programmatic control.
|
|
3
|
+
*
|
|
4
|
+
* Designed for parent processes like the mindstudio-sandbox C&C server.
|
|
5
|
+
* Input: newline-delimited JSON on stdin (e.g. {"action":"message","text":"..."})
|
|
6
|
+
* Output: newline-delimited JSON on stdout (e.g. {"event":"text","text":"..."})
|
|
7
|
+
*/
|
|
8
|
+
interface HeadlessOptions {
|
|
9
|
+
apiKey?: string;
|
|
10
|
+
baseUrl?: string;
|
|
11
|
+
model?: string;
|
|
12
|
+
lspUrl?: string;
|
|
13
|
+
}
|
|
14
|
+
declare function startHeadless(opts?: HeadlessOptions): Promise<void>;
|
|
15
|
+
|
|
16
|
+
export { type HeadlessOptions, startHeadless };
|