@assembly-js/app-foundation 0.0.31 → 0.0.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/CLAUDE.md +1 -1
- package/dist/bridge-vnext.d.ts +73 -0
- package/dist/bridge-vnext.js +13 -0
- package/dist/lib-client.d.ts +11 -0
- package/dist/lib-client.js +19 -0
- package/package.json +1 -1
- package/skills/assembly-ai/SKILL.md +24 -1
package/CLAUDE.md
CHANGED
|
@@ -43,7 +43,7 @@ Assembly-specific gotchas live in `.claude/skills/<name>/SKILL.md`. Invoke them
|
|
|
43
43
|
- `assembly-app-surfaces` — REQUIRED before writing `.assembly/app.json`: declare which surfaces (dashboard, client portal, notification) the app exposes; omitting the client surface keeps the app off client portal nav entirely
|
|
44
44
|
- `assembly-app-bridge-header` — breadcrumbs (don't include app name), CTAs
|
|
45
45
|
- `assembly-app-bridge-toast` — show toast notifications in the parent dashboard
|
|
46
|
-
- `assembly-ai` — AI features via Assembly's OpenAI proxy (no API keys needed)
|
|
46
|
+
- `assembly-ai` — AI features, including speech-to-text, via Assembly's OpenAI proxy (no API keys needed)
|
|
47
47
|
- `assembly-storage` — app-private file uploads/downloads (NOT the portal Files module). The storage helpers come from `@assembly-js/app-foundation/server` — import them, don't rewrite them. POST only `{ fileName }` (a bare name) and store the key the platform returns; never build the S3 key yourself.
|
|
48
48
|
- `assembly-integrations` (present only when third-party integrations are enabled for this workspace) — third-party providers (Slack, etc.) via `requiredIntegrations` + `getIntegration()`. If this skill is present, read it and `.claude/skills/assembly-integrations/providers/<slug>.md` before declaring an integration or writing any provider call — the skill lists what's connectable, the provider doc has that provider's gotchas — and read them first when provider data displays wrongly (wrong format, raw IDs). If it is absent, managed OAuth integrations are not available here; use `requiredSecrets` for any external service
|
|
49
49
|
- `assembly-avatar-sub` — AvatarSub company badge wherever a client is rendered, including tables of your own records that reference a client; row duplication only for lists OF clients
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import '@assembly-js/app-bridge';
|
|
2
|
+
export type NavigateDestination = {
|
|
3
|
+
to: 'home';
|
|
4
|
+
} | {
|
|
5
|
+
to: 'client';
|
|
6
|
+
clientId: string;
|
|
7
|
+
tab?: string;
|
|
8
|
+
} | {
|
|
9
|
+
to: 'company';
|
|
10
|
+
companyId: string;
|
|
11
|
+
tab?: string;
|
|
12
|
+
} | {
|
|
13
|
+
to: 'channel';
|
|
14
|
+
channelId?: string;
|
|
15
|
+
} | {
|
|
16
|
+
to: 'files';
|
|
17
|
+
channelId?: string;
|
|
18
|
+
} | {
|
|
19
|
+
to: 'contract';
|
|
20
|
+
contractId: string;
|
|
21
|
+
} | {
|
|
22
|
+
to: 'form';
|
|
23
|
+
formId: string;
|
|
24
|
+
} | {
|
|
25
|
+
to: 'formResponse';
|
|
26
|
+
formId: string;
|
|
27
|
+
responseId: string;
|
|
28
|
+
} | {
|
|
29
|
+
to: 'invoice';
|
|
30
|
+
invoiceId: string;
|
|
31
|
+
} | {
|
|
32
|
+
to: 'subscription';
|
|
33
|
+
subscriptionId: string;
|
|
34
|
+
} | {
|
|
35
|
+
to: 'product';
|
|
36
|
+
} | {
|
|
37
|
+
to: 'helpdesk';
|
|
38
|
+
} | {
|
|
39
|
+
to: 'article';
|
|
40
|
+
articleId: string;
|
|
41
|
+
} | {
|
|
42
|
+
to: 'notifications';
|
|
43
|
+
} | {
|
|
44
|
+
to: 'automations';
|
|
45
|
+
} | {
|
|
46
|
+
to: 'settings';
|
|
47
|
+
page?: string;
|
|
48
|
+
} | {
|
|
49
|
+
to: 'app';
|
|
50
|
+
installId: string;
|
|
51
|
+
};
|
|
52
|
+
export type NavigateToOptions = {
|
|
53
|
+
replace?: boolean;
|
|
54
|
+
newTab?: boolean;
|
|
55
|
+
timeout?: number;
|
|
56
|
+
};
|
|
57
|
+
export type NavigateResult = {
|
|
58
|
+
ok: true;
|
|
59
|
+
} | {
|
|
60
|
+
ok: false;
|
|
61
|
+
reason: string;
|
|
62
|
+
};
|
|
63
|
+
declare module '@assembly-js/app-bridge' {
|
|
64
|
+
interface AssemblyBridgeApi {
|
|
65
|
+
postToParent(message: {
|
|
66
|
+
type: string;
|
|
67
|
+
[key: string]: unknown;
|
|
68
|
+
}, options?: {
|
|
69
|
+
droppable?: boolean;
|
|
70
|
+
}): void;
|
|
71
|
+
navigateTo(destination: NavigateDestination, options?: NavigateToOptions): Promise<NavigateResult>;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// The published @assembly-js/app-bridge types this package typechecks against
|
|
2
|
+
// (peer >=1.3.0) predate the public postToParent and navigateTo. Both land on
|
|
3
|
+
// the 2.0.0 set, where they're required interface members. Augment rather
|
|
4
|
+
// than depending on an unpublished tarball; call sites guard with `?.` /
|
|
5
|
+
// truthiness checks since older peers lack these at runtime.
|
|
6
|
+
//
|
|
7
|
+
// Exported as real types (not just declared ambiently) because an ambient
|
|
8
|
+
// .d.ts that nothing imports never reaches a published package's declaration
|
|
9
|
+
// output — tsc only emits/carries declarations that are part of the module
|
|
10
|
+
// graph. lib-client.ts imports these types from this module instead of from
|
|
11
|
+
// '@assembly-js/app-bridge' so the augmentation travels with it to consumers
|
|
12
|
+
// on older peers, which don't export these names at all.
|
|
13
|
+
import '@assembly-js/app-bridge';
|
package/dist/lib-client.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { NavigateDestination, NavigateToOptions } from './bridge-vnext.js';
|
|
1
2
|
export declare function reexchangeBearer(): Promise<boolean>;
|
|
2
3
|
export declare function authFetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
3
4
|
export declare function downloadViaBlob(url: string, filename: string): Promise<void>;
|
|
@@ -9,3 +10,13 @@ export declare function downloadViaBlob(url: string, filename: string): Promise<
|
|
|
9
10
|
* Exported for tests; runs once at module load in the browser.
|
|
10
11
|
*/
|
|
11
12
|
export declare function bootstrapCookielessBearer(): Promise<boolean>;
|
|
13
|
+
/**
|
|
14
|
+
* Returns an onClick handler that navigates the parent Assembly portal to the
|
|
15
|
+
* given typed destination. Use in button or anchor onClick props.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* <button onClick={linkTo({ to: 'invoice', invoiceId: invoice.id })}>
|
|
19
|
+
* View invoice
|
|
20
|
+
* </button>
|
|
21
|
+
*/
|
|
22
|
+
export declare function linkTo(destination: NavigateDestination, options?: NavigateToOptions): () => void;
|
package/dist/lib-client.js
CHANGED
|
@@ -166,3 +166,22 @@ export function bootstrapCookielessBearer() {
|
|
|
166
166
|
// Self-running, mirroring origin-bootstrap: module evaluation precedes
|
|
167
167
|
// hydration, so the bearer is in hand before any component's first fetch.
|
|
168
168
|
void bootstrapCookielessBearer();
|
|
169
|
+
/**
|
|
170
|
+
* Returns an onClick handler that navigates the parent Assembly portal to the
|
|
171
|
+
* given typed destination. Use in button or anchor onClick props.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* <button onClick={linkTo({ to: 'invoice', invoiceId: invoice.id })}>
|
|
175
|
+
* View invoice
|
|
176
|
+
* </button>
|
|
177
|
+
*/
|
|
178
|
+
export function linkTo(destination, options) {
|
|
179
|
+
return () => {
|
|
180
|
+
// navigateTo rejects when the host never answers (e.g. the nav v2 flag is
|
|
181
|
+
// off) — catch it here, since the caller only gets a void onClick handler
|
|
182
|
+
// back and has no promise of its own to attach a handler to.
|
|
183
|
+
AssemblyBridge.navigateTo?.(destination, options)?.catch((err) => {
|
|
184
|
+
console.error('linkTo: navigateTo failed', err);
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: assembly-ai
|
|
3
|
-
description: Use when the app needs AI features like text generation, summarization, analysis, or any LLM capability. Apps call Assembly's AI proxy — no API keys or external SDKs needed.
|
|
3
|
+
description: Use when the app needs AI features like text generation, summarization, analysis, vision, speech-to-text, or any LLM capability. Apps call Assembly's AI proxy — no API keys or external SDKs needed.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
## How it works
|
|
@@ -96,6 +96,29 @@ const toDataUrl = (file: File): Promise<string> =>
|
|
|
96
96
|
|
|
97
97
|
Keep images under ~4 MB to stay within the 6 MB Lambda payload limit (base64 adds ~33% overhead). For larger images, resize on the client before converting.
|
|
98
98
|
|
|
99
|
+
## Audio (speech-to-text)
|
|
100
|
+
|
|
101
|
+
Record in the browser with `MediaRecorder` in the browser's native container: `audio/webm;codecs=opus`, or `audio/mp4` on Safari. Use a speech bitrate such as 24 kbps. Do not decode the recording to PCM or WAV in the browser.
|
|
102
|
+
|
|
103
|
+
Transcribe on the server. Post the file as `multipart/form-data` to `/v1/ai/openai/audio/transcriptions` through `assembly.fetch()`. Use `gpt-4o-mini-transcribe` (`whisper-1` is the alternative). Do not set a JSON `Content-Type` on this call. Pass the `FormData` as the body and let the runtime set the multipart header.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
export async function transcribeAudio(file: File) {
|
|
107
|
+
const assembly = await getAssembly();
|
|
108
|
+
const body = new FormData();
|
|
109
|
+
body.append('file', file);
|
|
110
|
+
body.append('model', 'gpt-4o-mini-transcribe');
|
|
111
|
+
const response = await assembly.fetch('/v1/ai/openai/audio/transcriptions', {
|
|
112
|
+
method: 'POST',
|
|
113
|
+
body,
|
|
114
|
+
});
|
|
115
|
+
if (!response.ok) throw new Error(`AI request failed: ${response.status}`);
|
|
116
|
+
return response;
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Keep each uploaded file under 4 MB. The platform API rejects request bodies above roughly 4.5 MB with HTTP 413 before the proxy runs, and there is no richer error to catch. Keep each file under about five minutes so the upstream call also finishes inside the proxy's 27 second first-byte timeout. For longer recordings, split the recording into files that meet both bounds and persist each transcript piece as it completes.
|
|
121
|
+
|
|
99
122
|
## Model selection
|
|
100
123
|
|
|
101
124
|
- Default to `gpt-4o-mini` for most tasks (fast, cheap, good enough)
|