@nyaruka/temba-components 0.156.12 → 0.156.14

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.
@@ -15,3 +15,20 @@ export function shouldExcludeFlow(flow: any): boolean {
15
15
 
16
16
  return false;
17
17
  }
18
+
19
+ export type LLMRole = 'engine' | 'editing';
20
+
21
+ export interface LLMModel {
22
+ uuid: string;
23
+ name: string;
24
+ type?: string;
25
+ description?: string;
26
+ roles?: LLMRole[];
27
+ }
28
+
29
+ export function hasLLMRole(
30
+ model: { roles?: string[] } | null | undefined,
31
+ role: LLMRole
32
+ ): boolean {
33
+ return model?.roles?.includes(role) ?? false;
34
+ }
@@ -8,6 +8,7 @@ import {
8
8
  renderLineItem,
9
9
  getLlmIcon
10
10
  } from '../utils';
11
+ import { LLMModel, hasLLMRole } from '../flow-utils';
11
12
 
12
13
  export const split_by_llm: NodeConfig = {
13
14
  type: 'split_by_llm',
@@ -47,7 +48,8 @@ export const split_by_llm: NodeConfig = {
47
48
  searchable: true,
48
49
  valueKey: 'uuid',
49
50
  nameKey: 'name',
50
- placeholder: 'Select an LLM...'
51
+ placeholder: 'Select an LLM...',
52
+ shouldExclude: (option: LLMModel) => !hasLLMRole(option, 'engine')
51
53
  },
52
54
  input: {
53
55
  type: 'text',
@@ -3,6 +3,7 @@ import { CallLLM, Node } from '../../store/flow-definition';
3
3
  import { generateUUID, createMultiCategoryRouter } from '../../utils';
4
4
  import { html } from 'lit';
5
5
  import { validateWith } from '../utils';
6
+ import { LLMModel, hasLLMRole } from '../flow-utils';
6
7
 
7
8
  export const split_by_llm_categorize: NodeConfig = {
8
9
  type: 'split_by_llm_categorize',
@@ -19,7 +20,8 @@ export const split_by_llm_categorize: NodeConfig = {
19
20
  endpoint: '/api/internal/llms.json',
20
21
  valueKey: 'uuid',
21
22
  nameKey: 'name',
22
- placeholder: 'Select an LLM...'
23
+ placeholder: 'Select an LLM...',
24
+ shouldExclude: (option: LLMModel) => !hasLLMRole(option, 'engine')
23
25
  },
24
26
  input: {
25
27
  type: 'text',
package/src/flow/types.ts CHANGED
@@ -50,7 +50,8 @@ export const CONTEXT_MENU_SHORTCUTS: Record<FlowType, ContextMenuShortcut[]> = {
50
50
  export const Features = {
51
51
  AI: 'ai',
52
52
  AIRTIME: 'airtime',
53
- LOCATIONS: 'locations'
53
+ LOCATIONS: 'locations',
54
+ AUTO_TRANSLATE: 'auto_translate'
54
55
  } as const;
55
56
 
56
57
  export type Feature = (typeof Features)[keyof typeof Features];
@@ -434,7 +434,10 @@ export class RichEditor extends FieldElement {
434
434
  }
435
435
 
436
436
  private handleKeydown(e: KeyboardEvent): void {
437
- const mod = e.metaKey || e.ctrlKey;
437
+ // On macOS, Cmd is the undo/redo modifier; leave Ctrl alone so Cocoa
438
+ // text bindings like Ctrl+K (kill) and Ctrl+Y (yank) keep working.
439
+ const isMac = /Mac|iPhone|iPad/.test(navigator.userAgent);
440
+ const mod = isMac ? e.metaKey : e.ctrlKey;
438
441
 
439
442
  // Undo/redo via keyboard: preventDefault here suppresses the subsequent
440
443
  // beforeinput event, avoiding double-handling
@@ -142,11 +142,26 @@ export class Dialog extends ResizeElement {
142
142
  flex-direction: row;
143
143
  align-items: center;
144
144
  font-size: 20px;
145
- padding: 12px 20px;
145
+ padding: 12px 20px var(--dialog-header-padding-bottom, 12px);
146
146
  color: var(--header-text);
147
147
  background: var(--header-bg);
148
148
  }
149
149
 
150
+ /* "flat" variant: header/footer share the body's white background
151
+ and lose their inner padding so the dialog reads as one
152
+ continuous surface. Use for content-focused dialogs that don't
153
+ need the tinted chrome. */
154
+ :host([variant='flat']) .header-text {
155
+ background: #fff;
156
+ color: var(--color-text);
157
+ padding-bottom: 0;
158
+ }
159
+
160
+ :host([variant='flat']) .dialog-footer {
161
+ background: #fff;
162
+ padding-top: 0;
163
+ }
164
+
150
165
  .header-text .title {
151
166
  flex-grow: 1;
152
167
  }
@@ -157,8 +172,11 @@ export class Dialog extends ResizeElement {
157
172
  }
158
173
 
159
174
  .dialog-footer {
160
- background: var(--color-primary-light);
161
- padding: 10px;
175
+ background: var(
176
+ --dialog-footer-background,
177
+ var(--color-primary-light)
178
+ );
179
+ padding: var(--dialog-footer-padding-top, 10px) 10px 10px;
162
180
  display: flex;
163
181
  flex-flow: row;
164
182
  align-items: center;
@@ -227,6 +245,9 @@ export class Dialog extends ResizeElement {
227
245
  @property({ type: Boolean })
228
246
  hideOnClick: boolean;
229
247
 
248
+ @property({ type: String, reflect: true })
249
+ variant: string;
250
+
230
251
  @property({ type: Boolean })
231
252
  noFocus: boolean;
232
253
 
@@ -6,13 +6,22 @@
6
6
  "uuid": "2399e7d6-fcdf-4e47-a835-f3bdb7f80938",
7
7
  "name": "GPT 4.1",
8
8
  "type": "openai",
9
- "description": "General-purpose reasoning model"
9
+ "description": "General-purpose reasoning model",
10
+ "roles": ["engine", "editing"]
10
11
  },
11
12
  {
12
13
  "uuid": "4399e7d6-fcdf-4e47-a835-f3bdb7f80938",
13
14
  "name": "GPT 5",
14
15
  "type": "openai",
15
- "description": "Latest experimental model"
16
+ "description": "Latest experimental model",
17
+ "roles": ["engine"]
18
+ },
19
+ {
20
+ "uuid": "5499e7d6-fcdf-4e47-a835-f3bdb7f80938",
21
+ "name": "GPT 4.1 Mini",
22
+ "type": "openai",
23
+ "description": "Lightweight model for editing tasks",
24
+ "roles": ["editing"]
16
25
  }
17
26
  ]
18
27
  }
package/temba-modules.ts CHANGED
@@ -85,6 +85,7 @@ import { Simulator } from './src/simulator/Simulator';
85
85
  import { FlowSearch } from './src/flow/FlowSearch';
86
86
  import { IssuesWindow } from './src/flow/IssuesWindow';
87
87
  import { RevisionsWindow } from './src/flow/RevisionsWindow';
88
+ import { AutoTranslate } from './src/flow/AutoTranslate';
88
89
  import { MessageTable } from './src/flow/MessageTable';
89
90
 
90
91
  export function addCustomElement(name: string, comp: any) {
@@ -182,3 +183,4 @@ addCustomElement('temba-simulator', Simulator);
182
183
  addCustomElement('temba-flow-search', FlowSearch);
183
184
  addCustomElement('temba-issues-window', IssuesWindow);
184
185
  addCustomElement('temba-revisions-window', RevisionsWindow);
186
+ addCustomElement('temba-auto-translate', AutoTranslate);