@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.
@@ -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 };