@proteos/sdk 0.32.1 → 0.34.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.
@@ -7,7 +7,7 @@ export type ConnectionStatus = 'pending' | 'active' | 'error' | 'revoked'
7
7
  export type ConnectionScope = 'org' | 'user'
8
8
 
9
9
  /** How a connector authenticates. */
10
- export type CredentialKind = 'oauth' | 'api_key' | 'basic' | 'bot_token'
10
+ export type CredentialKind = 'oauth' | 'api_key' | 'basic' | 'bot_token' | 'service_account'
11
11
 
12
12
  export interface UserRef {
13
13
  type: string
@@ -45,6 +45,17 @@ export interface ConnectorOAuthConfig {
45
45
  client_secret_variable_key: string
46
46
  }
47
47
 
48
+ /**
49
+ * The service-account wiring of a connector supporting the service_account
50
+ * kind. Like the OAuth app credentials, the SA key is an org VARIABLE —
51
+ * key_variable_key names the default; a connection may reference its own via
52
+ * settings.service_account_key_variable.
53
+ */
54
+ export interface ConnectorServiceAccountConfig {
55
+ key_variable_key: string
56
+ scopes: string[]
57
+ }
58
+
48
59
  /** A connector TYPE (google-calendar, a customer's vertex-tax, …). */
49
60
  export interface Connector {
50
61
  key: string
@@ -53,12 +64,21 @@ export interface Connector {
53
64
  description?: string
54
65
  icon?: string
55
66
  credential_kind: CredentialKind
67
+ /** Every kind a connection may use; absent/empty = exactly [credential_kind]. */
68
+ supported_credential_kinds?: CredentialKind[]
56
69
  oauth?: ConnectorOAuthConfig
70
+ service_account?: ConnectorServiceAccountConfig
57
71
  /**
58
72
  * COMPUTED: the broker's per-environment OAuth callback — register it as an
59
73
  * authorized redirect URI on the provider app.
60
74
  */
61
75
  oauth_redirect_uri?: string
76
+ /**
77
+ * COMPUTED: the environment ships platform-default OAuth app credentials
78
+ * for this connector, so the connect wizard can skip collecting them.
79
+ * Org variables always override the default.
80
+ */
81
+ has_default_app_credentials?: boolean
62
82
  config_schema?: Attribute[]
63
83
  methods: ConnectorMethod[]
64
84
  origin: 'pre_built' | 'custom'
@@ -79,6 +99,8 @@ export interface ConnectorConnection {
79
99
  scope: ConnectionScope
80
100
  owner?: UserRef
81
101
  external_account_id: string
102
+ /** Redacted {kind, data} credential envelope — secrets are masked; use kind to tell how the connection authenticates. */
103
+ credentials?: { kind: CredentialKind; data?: Record<string, unknown> }
82
104
  settings: Record<string, unknown>
83
105
  status: ConnectionStatus
84
106
  status_detail?: string
@@ -40,6 +40,7 @@ import type {
40
40
  RecordPermissionEventRequest,
41
41
  Room,
42
42
  SendMessageRequest,
43
+ SyncConnectionRequest,
43
44
  Transcription,
44
45
  UnreadCounts,
45
46
  UpdateAgentListenerRequest,
@@ -106,10 +107,17 @@ export interface MeetingService {
106
107
  /** Make the bot leave the meeting and end the conversation (by conversation id). */
107
108
  remove(conversationId: string): Promise<Conversation>
108
109
  /**
109
- * Regenerate this meeting conversation's markdown summary from its stored
110
- * transcript, overwriting any existing one. Resolves with the updated
111
- * conversation (its fresh `summary`). Rejects with `no_transcript` when the
112
- * conversation has no completed transcript to summarize.
110
+ * START regenerating this meeting conversation's markdown summary from its
111
+ * stored transcript, overwriting any existing one when it lands. Generation
112
+ * runs server-side beyond this request, so the promise resolves as soon as the
113
+ * conversation is CLAIMED with `summary_status: 'processing'` and the OLD
114
+ * `summary` still attached. Poll `conversations.get(id)` until
115
+ * `summary_status` is `completed` (or `failed`) to read the new one.
116
+ *
117
+ * Rejects with `no_transcript` when the conversation has no completed
118
+ * transcript to summarize, `summarization_unavailable` when the environment
119
+ * has no generator configured, and `summary_in_progress` when a generation is
120
+ * already running for this conversation.
113
121
  */
114
122
  summarize(conversationId: string): Promise<Conversation>
115
123
  }
@@ -145,6 +153,15 @@ export interface ConnectionService {
145
153
  delete(id: string): Promise<void>
146
154
  /** Begin the connector's install flow; open the returned URL in a popup. */
147
155
  install(id: string): Promise<InstallConnectionResponse>
156
+ /**
157
+ * Trigger a historical backfill ("sync all") on an email connection: the
158
+ * server fetches provider mail in the chosen range and ingests it through
159
+ * the normal pipeline (conversation filters, dedupe, agent listeners).
160
+ * Returns 202 with the connection already showing
161
+ * settings.sync_status='in_progress' — poll get(id) until it flips to
162
+ * done/failed. A running sync answers 409 (sync_already_running).
163
+ */
164
+ sync(id: string, request: SyncConnectionRequest): Promise<Connection>
148
165
  /** Search the contact addresses this connection can reach (org-deduped) for the compose picker. */
149
166
  listContactAddresses(
150
167
  connectionId: string,
@@ -194,6 +211,14 @@ class ConnectionServiceImpl implements ConnectionService {
194
211
  )
195
212
  }
196
213
 
214
+ sync(id: string, request: SyncConnectionRequest): Promise<Connection> {
215
+ return this.client.request(
216
+ 'POST',
217
+ `${CONVERSATION_BASE_PATH}/connections/${encodeURIComponent(id)}/sync`,
218
+ request,
219
+ )
220
+ }
221
+
197
222
  listContactAddresses(
198
223
  connectionId: string,
199
224
  query: ListContactAddressesQuery = {},
@@ -41,6 +41,7 @@ export type Channel =
41
41
  export type ConnectorKey =
42
42
  | 'slack'
43
43
  | 'gmail'
44
+ | 'outlook'
44
45
  | 'echo'
45
46
  | 'unipile-whatsapp'
46
47
  | 'unipile-linkedin'
@@ -73,6 +74,15 @@ export type ConnectionStatus = 'pending' | 'active' | 'error' | 'revoked'
73
74
  * drafting) — hidden from the default list until the first successful send.
74
75
  */
75
76
  export type ConversationStatus = 'active' | 'ended' | 'archived' | 'draft'
77
+ /**
78
+ * Generation lifecycle of a conversation's `summary`. `none` is the resting
79
+ * default — no summary exists and none is being produced, the state of every
80
+ * conversation that is not a transcript-backed meeting. `processing` is claimed
81
+ * for the duration of one generation run (automatic at transcript attach, or a
82
+ * manual `meetings.summarize()`), so any client can render "Summarizing…"
83
+ * without having started the run itself.
84
+ */
85
+ export type ConversationSummaryStatus = 'none' | 'processing' | 'completed' | 'failed'
76
86
  export type AgentListenerTriggerType = 'always' | 'mention' | 'channel' | 'keyword'
77
87
 
78
88
  export interface UserRef {
@@ -166,6 +176,20 @@ export interface ReactionCapability {
166
176
  max_per_actor: number
167
177
  }
168
178
 
179
+ /** How far back a historical backfill ("sync all") reaches. */
180
+ export type ConnectionSyncRange = '30d' | '90d' | '365d' | 'all'
181
+
182
+ /**
183
+ * Lifecycle of a historical backfill, carried as settings.sync_status.
184
+ * Absent key = 'none' (never synced). 'in_progress' is claimed before the
185
+ * trigger request returns — poll get(id) until it flips to done/failed.
186
+ */
187
+ export type ConnectionSyncStatus = 'none' | 'in_progress' | 'done' | 'failed'
188
+
189
+ export interface SyncConnectionRequest {
190
+ range: ConnectionSyncRange
191
+ }
192
+
169
193
  export interface Connection {
170
194
  id: string
171
195
  org_id: string
@@ -177,6 +201,11 @@ export interface Connection {
177
201
  owner?: UserRef
178
202
  external_account_id: string
179
203
  credentials: ConnectionCredentials
204
+ /**
205
+ * Connector-shaped configuration + state. A historical backfill writes the
206
+ * sync_* keys here: sync_status (ConnectionSyncStatus), sync_range,
207
+ * sync_started_at, sync_completed_at, sync_synced_count, sync_error.
208
+ */
180
209
  settings: Record<string, unknown>
181
210
  status: ConnectionStatus
182
211
  /** Computed on read: the connector implements the reaction capability. */
@@ -207,6 +236,16 @@ export interface Conversation {
207
236
  * conversations, editable via update(). Absent when no summary exists.
208
237
  */
209
238
  summary?: string
239
+ /**
240
+ * Generation lifecycle of `summary`. Poll `conversations.get(id)` while this
241
+ * reads `processing` to pick up the finished summary.
242
+ */
243
+ summary_status: ConversationSummaryStatus
244
+ /**
245
+ * When the current `processing` run was claimed; absent otherwise. Bounds the
246
+ * claim server-side and gives clients an elapsed time to show.
247
+ */
248
+ summary_started_at?: string
210
249
  status: ConversationStatus
211
250
  /**
212
251
  * Room directory row a room-borne thread (Slack channel conversation) lives
package/src/index.ts CHANGED
@@ -198,6 +198,8 @@ export type {
198
198
  ConnectionScope,
199
199
  ConnectionService,
200
200
  ConnectionStatus,
201
+ ConnectionSyncRange,
202
+ ConnectionSyncStatus,
201
203
  ConnectorKey,
202
204
  ConnectorProvider,
203
205
  ConsentStatus,
@@ -223,6 +225,7 @@ export type {
223
225
  ConversationParticipant,
224
226
  ConversationService,
225
227
  ConversationStatus,
228
+ ConversationSummaryStatus,
226
229
  CreateAgentListenerRequest,
227
230
  CreateConnectionRequest,
228
231
  CreateConversationFilterRequest,
@@ -271,6 +274,7 @@ export type {
271
274
  Room,
272
275
  SendMessageRequest,
273
276
  SendRecipient,
277
+ SyncConnectionRequest,
274
278
  TranscribeStreamOptions,
275
279
  TranscriptResult,
276
280
  UnreadCounts,
@@ -421,6 +425,8 @@ export type {
421
425
  // App types
422
426
  App,
423
427
  AppService,
428
+ // Array/enum attribute metas (config_schema renderers narrow on these)
429
+ ArrayAttributeMeta,
424
430
  Attribute,
425
431
  AttributeType,
426
432
  Column,
@@ -450,6 +456,8 @@ export type {
450
456
  Entity,
451
457
  EntityService,
452
458
  EntityWithSchema,
459
+ EnumAttributeMeta,
460
+ EnumValue,
453
461
  // File attribute meta
454
462
  FileAttributeMeta,
455
463
  FilterElement,
@@ -589,7 +597,6 @@ export {
589
597
  } from './types/index.js'
590
598
  export type {
591
599
  AgentActionParams,
592
- AgentKickoff,
593
600
  BinaryRef,
594
601
  ConnectionEndpoint,
595
602
  CreateWorkflowRequest,
@@ -613,8 +620,8 @@ export type {
613
620
  ListExecutionsOptions,
614
621
  ListWorkflowsOptions,
615
622
  ManualTriggerParams,
616
- MessageKickoff,
617
623
  MessageTriggerParams,
624
+ ModelCallParams,
618
625
  NodeDescriptor,
619
626
  NodeExecution,
620
627
  NodeGroup,
@@ -627,13 +634,12 @@ export type {
627
634
  NodeTypeService,
628
635
  NodeTypeStatus,
629
636
  OnErrorPolicy,
630
- OutcomeKickoff,
631
- OutcomeRubric,
632
637
  PairedItem,
633
638
  PortSpec,
634
639
  PropertyOption,
635
640
  PropertyType,
636
641
  RunWorkflowRequest,
642
+ SystemSource,
637
643
  TestNodeCandidate,
638
644
  TestNodeInputSource,
639
645
  TestNodeRequest,
@@ -643,7 +649,6 @@ export type {
643
649
  WebhookTriggerParams,
644
650
  Workflow,
645
651
  WorkflowConnection,
646
- WorkflowContentBlock,
647
652
  WorkflowExecution,
648
653
  WorkflowGraph,
649
654
  WorkflowNode,
@@ -15,6 +15,7 @@ export const LayoutElementType = {
15
15
  Tabs: 'tabs',
16
16
  Field: 'field',
17
17
  RelatedList: 'related_list',
18
+ RelatedRecord: 'related_record',
18
19
  Component: 'component',
19
20
  Divider: 'divider',
20
21
  Text: 'text',
@@ -96,6 +97,31 @@ export type RelatedListElement = CommonProps & {
96
97
  follows_parent_edit_mode?: boolean
97
98
  }
98
99
 
100
+ /**
101
+ * Renders the FIRST record of `related_entity_slug` that references the
102
+ * current record through the `via_attribute` relation attribute — the
103
+ * singular counterpart of `related_list`, addressing the relation the same
104
+ * inbound way. The match is taken oldest-first so the choice is stable.
105
+ *
106
+ * `page_slug` optionally pins which record page supplies the layout; when
107
+ * omitted (or dangling) the renderer falls back to the related entity's
108
+ * default record page. The element renders that page bare — wrap it in a
109
+ * `section` element for a title or collapse affordance.
110
+ */
111
+ export type RelatedRecordElement = CommonProps & {
112
+ type: 'related_record'
113
+ related_entity_slug: string
114
+ via_attribute: string
115
+ page_slug?: string
116
+ /**
117
+ * When absent or true, the element enters edit mode together with the host
118
+ * page's edit mode. False keeps it independent — editable only through its
119
+ * own hover control. Either way the element saves the related record
120
+ * itself; the host page's Save never covers it.
121
+ */
122
+ follows_parent_edit_mode?: boolean
123
+ }
124
+
99
125
  export type ComponentElement = CommonProps & {
100
126
  type: 'component'
101
127
  component_slug: string
@@ -127,6 +153,7 @@ export type LayoutElement =
127
153
  | TabsElement
128
154
  | FieldElement
129
155
  | RelatedListElement
156
+ | RelatedRecordElement
130
157
  | ComponentElement
131
158
  | DividerElement
132
159
  | TextElement
@@ -196,6 +223,14 @@ export const LayoutElementSchema: z.ZodType<LayoutElement> = z.lazy(() =>
196
223
  list_slug: z.string().min(1).optional(),
197
224
  follows_parent_edit_mode: z.boolean().optional(),
198
225
  }),
226
+ z.object({
227
+ type: z.literal('related_record'),
228
+ ...commonPropsShape,
229
+ related_entity_slug: z.string().min(1),
230
+ via_attribute: z.string().min(1),
231
+ page_slug: z.string().min(1).optional(),
232
+ follows_parent_edit_mode: z.boolean().optional(),
233
+ }),
199
234
  z.object({
200
235
  type: z.literal('component'),
201
236
  ...commonPropsShape,
@@ -26,6 +26,7 @@ export {
26
26
  LayoutElementType,
27
27
  type LayoutTab,
28
28
  type RelatedListElement,
29
+ type RelatedRecordElement,
29
30
  type RowElement,
30
31
  type SectionElement,
31
32
  type TabsElement,
package/src/meta/types.ts CHANGED
@@ -782,6 +782,8 @@ export interface List extends AuditFields {
782
782
  name: string
783
783
  entity_slug: string
784
784
  columns: Column[]
785
+ /** Record page to open from this list; empty/absent = org default for the entity. */
786
+ default_page_slug?: string
785
787
  sorting: SortConfig[]
786
788
  filters: FilterGroup[]
787
789
  }
@@ -803,6 +805,7 @@ export const ListSchema = AuditFieldsSchema.extend({
803
805
  name: z.string(),
804
806
  entity_slug: z.string(),
805
807
  columns: z.array(ColumnSchema),
808
+ default_page_slug: z.string().optional(),
806
809
  sorting: z.array(SortConfigSchema),
807
810
  filters: z.array(FilterGroupSchema),
808
811
  })
@@ -826,6 +829,7 @@ export interface CreateListRequest {
826
829
  entity_slug: string
827
830
  name: string
828
831
  columns: Column[]
832
+ default_page_slug?: string
829
833
  sorting: SortConfig[]
830
834
  filters: FilterGroup[]
831
835
  }
@@ -837,6 +841,8 @@ export interface UpdateListRequest {
837
841
  name?: string
838
842
  module_slug?: string
839
843
  columns?: Column[]
844
+ /** Set to '' to clear back to the org default. */
845
+ default_page_slug?: string
840
846
  sorting?: SortConfig[]
841
847
  filters?: FilterGroup[]
842
848
  }
@@ -42,7 +42,6 @@ export type { ExecutionService } from './executions.js'
42
42
  export type { NodeTypeService } from './node-types.js'
43
43
  export type {
44
44
  AgentActionParams,
45
- AgentKickoff,
46
45
  BinaryRef,
47
46
  ConnectionEndpoint,
48
47
  CreateWorkflowRequest,
@@ -66,8 +65,8 @@ export type {
66
65
  ListExecutionsOptions,
67
66
  ListWorkflowsOptions,
68
67
  ManualTriggerParams,
69
- MessageKickoff,
70
68
  MessageTriggerParams,
69
+ ModelCallParams,
71
70
  NodeDescriptor,
72
71
  NodeExecution,
73
72
  NodeGroup,
@@ -79,13 +78,12 @@ export type {
79
78
  NodeTypeKey,
80
79
  NodeTypeStatus,
81
80
  OnErrorPolicy,
82
- OutcomeKickoff,
83
- OutcomeRubric,
84
81
  PairedItem,
85
82
  PortSpec,
86
83
  PropertyOption,
87
84
  PropertyType,
88
85
  RunWorkflowRequest,
86
+ SystemSource,
89
87
  TestNodeCandidate,
90
88
  TestNodeInputSource,
91
89
  TestNodeRequest,
@@ -95,7 +93,6 @@ export type {
95
93
  WebhookTriggerParams,
96
94
  Workflow,
97
95
  WorkflowConnection,
98
- WorkflowContentBlock,
99
96
  WorkflowExecution,
100
97
  WorkflowGraph,
101
98
  WorkflowNode,
@@ -13,6 +13,7 @@
13
13
  * workflow; per-node results live in append-only NodeExecution rows.
14
14
  */
15
15
 
16
+ import type { Attribute } from '../meta/types.js'
16
17
  import type { AuditFields, ListOptions, UserRef } from '../types/common.js'
17
18
 
18
19
  // ---------------------------------------------------------------------------
@@ -163,6 +164,8 @@ export type PropertyType =
163
164
  | 'fixed_collection'
164
165
  | 'credentials_select'
165
166
  | 'button'
167
+ /** Edits a platform attribute list (`Attribute[]`) via the shared attribute schema builder. */
168
+ | 'attribute_schema'
166
169
  // Wave 2 (editor support lands with Phase 3):
167
170
  | 'resource_locator'
168
171
  | 'resource_mapper'
@@ -355,54 +358,86 @@ export interface MessageTriggerParams {
355
358
  event_types?: string[]
356
359
  }
357
360
 
358
- export type KickoffType = 'message' | 'outcome'
361
+ /** Matches every event type on the subscribed topic. */
362
+ export const PLATFORM_EVENT_WILDCARD = '*'
359
363
 
360
364
  /**
361
- * Where a kickoff draws its instruction text from: typed inline (`manual`) or
362
- * resolved from a reusable agent-service Prompt by key (`prompt`) at run time.
365
+ * Fires the workflow when an event whose type is in `event_types` arrives on
366
+ * the named platform bus topic. Unlike {@link EventTriggerParams} (records
367
+ * only), any per-org topic in the event catalog is a valid target.
368
+ *
369
+ * `event_types` may hold the single wildcard `'*'` to match every type — custom
370
+ * topics have no catalogued type list, so there is nothing to enumerate.
363
371
  */
364
- export type KickoffSource = 'manual' | 'prompt'
365
-
366
- export interface WorkflowContentBlock {
367
- type: 'text' | 'file'
368
- text?: string
369
- file_id?: string
372
+ export interface PlatformEventTriggerParams {
373
+ topic: string
374
+ event_types: string[]
370
375
  }
371
376
 
372
- export interface MessageKickoff {
373
- source?: KickoffSource
374
- /** Inline content blocks (manual source). */
375
- content?: WorkflowContentBlock[]
376
- /** Prompt key whose body becomes the message text (prompt source). */
377
- prompt_key?: string
378
- }
377
+ export type KickoffType = 'message' | 'outcome'
379
378
 
380
- export interface OutcomeRubric {
381
- type: 'text' | 'file'
382
- content?: string
383
- file_id?: string
384
- }
379
+ /**
380
+ * Where a kickoff slot draws its instruction text from: typed inline
381
+ * (`manual`) or resolved from a reusable agent-service Prompt by key
382
+ * (`prompt`) at run time.
383
+ */
384
+ export type KickoffSource = 'manual' | 'prompt'
385
385
 
386
- export interface OutcomeKickoff {
387
- /** Description and rubric are independently sourced (manual vs prompt). */
386
+ /**
387
+ * Flat, descriptor-driven parameters of the `action.agent` node (gated by
388
+ * display_options on `kickoff_type` / `*_source`). `output_schema` declares
389
+ * the node's structured output as platform attributes — the agent records it
390
+ * via the session-scoped `set_output` tool; `is_output_required` fails the
391
+ * node when the agent finishes without setting it.
392
+ */
393
+ export interface AgentActionParams {
394
+ agent_key: string
395
+ kickoff_type: KickoffType
396
+ message_source?: KickoffSource
397
+ message_text?: string
398
+ message_prompt_key?: string
388
399
  description_source?: KickoffSource
389
400
  description?: string
390
401
  description_prompt_key?: string
391
402
  rubric_source?: KickoffSource
392
- rubric?: OutcomeRubric
403
+ rubric_type?: 'text' | 'file'
404
+ rubric_content?: string
405
+ rubric_file_id?: string
393
406
  rubric_prompt_key?: string
394
407
  max_iterations?: number
408
+ output_schema?: Attribute[]
409
+ is_output_required?: boolean
395
410
  }
396
411
 
397
- export interface AgentKickoff {
398
- type: KickoffType
399
- message?: MessageKickoff
400
- outcome?: OutcomeKickoff
401
- }
412
+ /**
413
+ * Where a model call's optional system instruction comes from. Empty/absent
414
+ * defaults to `none`.
415
+ */
416
+ export type SystemSource = 'none' | 'manual' | 'prompt'
402
417
 
403
- export interface AgentActionParams {
404
- agent_key: string
405
- kickoff: AgentKickoff
418
+ /**
419
+ * Flat, descriptor-driven parameters of the `proteos-nodes-core.model-call`
420
+ * node: one stateless LLM call per input item. The prompt and the optional
421
+ * system instruction are independently sourced — typed inline (`manual`,
422
+ * Liquid-resolved per item) or resolved verbatim from a reusable Prompt by key
423
+ * (`prompt`). With `has_structured_output`, `output_schema` declares the
424
+ * reply's shape as platform attributes: generation is schema-constrained
425
+ * (forced tool) AND the node validates the returned JSON, failing the item
426
+ * after one automatic repair attempt.
427
+ */
428
+ export interface ModelCallParams {
429
+ /** Empty resolves to the platform default model. */
430
+ model_id?: string
431
+ temperature?: number
432
+ max_tokens?: number
433
+ prompt_source?: KickoffSource
434
+ prompt_text?: string
435
+ prompt_key?: string
436
+ system_source?: SystemSource
437
+ system_text?: string
438
+ system_prompt_key?: string
439
+ has_structured_output?: boolean
440
+ output_schema?: Attribute[]
406
441
  }
407
442
 
408
443
  // ---------------------------------------------------------------------------
@@ -544,7 +579,15 @@ export type ExecutionStatus =
544
579
  | 'cancelled'
545
580
  | 'skipped'
546
581
 
547
- export type TriggerKind = 'schedule' | 'manual' | 'webhook' | 'event' | 'message' | 'workflow'
582
+ export type TriggerKind =
583
+ | 'schedule'
584
+ | 'manual'
585
+ | 'webhook'
586
+ | 'event'
587
+ | 'message'
588
+ | 'connector'
589
+ | 'platform_event'
590
+ | 'workflow'
548
591
 
549
592
  /**
550
593
  * Why and how an execution fired. Flat, kind-discriminated: `kind` selects