@tagit/ai-client-core 1.7.0-beta.54.1 → 1.7.0-beta.57.1

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 CHANGED
@@ -1,14 +1,14 @@
1
1
  # @tagit/ai-client-core
2
2
 
3
- Headless TypeScript client core for the tagIt AI orchestrator.
3
+ Headless TypeScript client core for the Knotiv AI Orchestrator.
4
4
 
5
5
  Use this package when you want to talk to the orchestrator directly and manage your own UI. It owns request shaping, streaming, retries, cancellation, conversation state, and optional collector emission.
6
6
 
7
7
  This README is the source of truth for the core package.
8
8
 
9
- ## What Is tagIt?
9
+ ## What Is Knotiv?
10
10
 
11
- tagIt is the platform for building governed AI experiences. It gives teams a way to define AI use cases, connect models, optionally attach MCP servers, and shape the orchestration logic that drives the overall experience.
11
+ Knotiv is the platform for building governed AI experiences. It gives teams a way to define AI use cases, connect models, optionally attach MCP servers, and shape the orchestration logic that drives the overall experience.
12
12
 
13
13
  ## What Is the AI Orchestrator?
14
14
 
@@ -16,11 +16,11 @@ The AI Orchestrator is the runtime layer that executes a use case. It combines t
16
16
 
17
17
  ## Why This Package Exists
18
18
 
19
- `@tagit/ai-client-core` is the client-side engine that connects your app to a tagIt account and a configured AI Orchestrator. You need a tagIt account and at least one configured use case before this package can drive a real experience.
19
+ `@tagit/ai-client-core` is the client-side engine that connects your app to a Knotiv account and a configured AI Orchestrator. You need a Knotiv account and at least one configured Agent before this package can drive a real experience.
20
20
 
21
21
  MCP servers are optional, but they can extend the orchestrator with tools and external capabilities.
22
22
 
23
- To learn more about tagIt and the orchestrator setup, visit [tagit.live](https://tagit.live).
23
+ To learn more about Knotiv and Orchestrator setup, visit [knotiv.com](https://knotiv.com).
24
24
 
25
25
  ## What This Package Provides
26
26
 
@@ -54,7 +54,7 @@ npm install @tagit/ai-client-core
54
54
  import { AIClient, createDefaultConfig } from '@tagit/ai-client-core';
55
55
 
56
56
  const client = new AIClient(
57
- createDefaultConfig('uc-default-1lji40', 'https://ai.tagit.live', {
57
+ createDefaultConfig('uc-default-1lji40', window.location.origin, {
58
58
  user: {
59
59
  entityId: 'anonymous-or-authenticated-user-id',
60
60
  userId: 'optional-friendly-user-id',
@@ -67,11 +67,6 @@ const client = new AIClient(
67
67
  title: 'Optional conversation title',
68
68
  memoryMaxTurns: 6,
69
69
  },
70
- conversationHistory: {
71
- enabled: true,
72
- surface: '/optional/page-or-product-surface',
73
- recentLimit: 5,
74
- },
75
70
  agents: [
76
71
  {
77
72
  useCaseId: 'uc-default-1lji40',
@@ -79,9 +74,6 @@ const client = new AIClient(
79
74
  description: 'General product help.',
80
75
  },
81
76
  ],
82
- orchestrator: {
83
- apiKey: import.meta.env.VITE_TAGIT_AI_ORCHESTRATOR_API_KEY,
84
- },
85
77
  collector: {
86
78
  enabled: false,
87
79
  },
@@ -89,6 +81,12 @@ const client = new AIClient(
89
81
  );
90
82
  ```
91
83
 
84
+ This browser example calls your application's same-origin `POST /v2/chat`
85
+ route. That route authenticates the caller, selects or validates the permitted
86
+ Agent, and forwards the request to Knotiv with the server-only API key. Do not
87
+ put an Orchestrator API key in `VITE_*`, `NEXT_PUBLIC_*`, or any other
88
+ browser-readable environment variable.
89
+
92
90
  ## Core Concepts
93
91
 
94
92
  ### `AIClient`
@@ -123,7 +121,7 @@ The core client is driven by a validated `ClientConfig`. If a field is omitted,
123
121
  This helper builds a safe starting config.
124
122
 
125
123
  ```ts
126
- const config = createDefaultConfig('uc-default-1lji40', 'https://ai.tagit.live', {
124
+ const config = createDefaultConfig('uc-default-1lji40', window.location.origin, {
127
125
  collector: {
128
126
  enabled: false,
129
127
  },
@@ -133,11 +131,12 @@ const config = createDefaultConfig('uc-default-1lji40', 'https://ai.tagit.live',
133
131
  | Field | Type / values | Default | What it does | Example |
134
132
  |---|---|---:|---|---|
135
133
  | `useCaseId` | `string` | required | Runtime use case identifier used by the orchestrator. | `'uc-default-1lji40'` |
136
- | `orchestratorUrl` | URL string | required | Base URL for the orchestrator. Do not include `/v2/chat`. | `'https://ai.tagit.live'` |
137
- | `options.orchestrator` | partial orchestrator config | `undefined` | Overrides specific orchestrator fields. | `{ apiKey: '...' }` |
134
+ | `orchestratorUrl` | URL string | required | Base URL for the request path. In browser code, use your application's same-origin origin. Do not include `/v2/chat`. | `window.location.origin` |
135
+ | `options.orchestrator` | partial orchestrator config | `undefined` | Overrides specific orchestrator fields. | `{ timeoutMs: 30000 }` |
138
136
  | `options.user` | user identity config | `undefined` | Shared identity used by orchestrator memory and collector events. | `{ entityId: 'user_123' }` |
139
137
  | `options.conversation` | conversation config | `undefined` | Durable conversation id, title, and memory window. | `{ memoryMaxTurns: 6 }` |
140
138
  | `options.conversationHistory` | history config | `undefined` | Enables durable list/load and lifecycle APIs. | `{ enabled: true }` |
139
+ | `options.resources` | resource workspace config | `undefined` | Enables private file upload, selection, and conversation attachments through a host-authenticated transport. | `{ enabled: true, transport }` |
141
140
  | `options.agents` | `AgentOption[]` | `undefined` | Optional host-authorized agents available to this client instance. | `[{ useCaseId, name }]` |
142
141
  | `options.defaultUseCaseId` | string | `undefined` | Initial active agent when `agents` is supplied. | `'uc-support'` |
143
142
  | `options.onActiveAgentChange` | function | `undefined` | Callback when the initial or selected agent becomes active. | `(agent) => setAgent(agent)` |
@@ -151,7 +150,7 @@ Use `agents` when one embedded client should let the user switch between multipl
151
150
 
152
151
  ```ts
153
152
  const client = new AIClient(
154
- createDefaultConfig('uc-platform-help', 'https://ai.tagit.live', {
153
+ createDefaultConfig('uc-platform-help', window.location.origin, {
155
154
  agents: [
156
155
  {
157
156
  useCaseId: 'uc-platform-help',
@@ -185,7 +184,7 @@ The SDK calls the resolver immediately before each send. The host decides what v
185
184
 
186
185
  ```ts
187
186
  const client = new AIClient(
188
- createDefaultConfig('uc-platform-help', 'https://ai.tagit.live', {
187
+ createDefaultConfig('uc-platform-help', window.location.origin, {
189
188
  user: { entityId: currentUser.uid, userId: currentUser.uid },
190
189
  agents,
191
190
  resolveRequestOptions(agent, context) {
@@ -250,15 +249,72 @@ When `conversationHistory.enabled` is `true`, the client must be able to resolve
250
249
  | `conversationHistory.newConversationId` | function | no | Custom durable conversation id generator. | `() => crypto.randomUUID()` |
251
250
  | `conversationHistory.transport` | `ConversationHistoryTransport` | no | Custom history transport. Constructor transport option takes precedence. | `customTransport` |
252
251
 
252
+ ### Private Resource Workspace Config
253
+
254
+ `resources` enables governed private files and conversation attachments. The
255
+ host remains responsible for authentication and Workspace selection. The SDK
256
+ never accepts a user ID, account ID, or Workspace ID from the model.
257
+
258
+ Use `FetchConversationResourceTransport` with a short-lived signed-in user
259
+ token, or provide a custom server-backed `ConversationResourceTransport`.
260
+
261
+ ```ts
262
+ import {
263
+ AIClient,
264
+ FetchConversationResourceTransport,
265
+ createDefaultConfig,
266
+ } from '@tagit/ai-client-core';
267
+
268
+ const resourceTransport = new FetchConversationResourceTransport({
269
+ baseUrl: 'https://beta.knotiv.com',
270
+ accountId,
271
+ contextId: workspaceId,
272
+ headers: async () => ({
273
+ Authorization: `Bearer ${await currentUser.getIdToken()}`,
274
+ }),
275
+ });
276
+
277
+ const client = new AIClient(
278
+ createDefaultConfig(useCaseId, orchestratorUrl, {
279
+ user: { entityId: currentUser.uid, userId: currentUser.uid },
280
+ resources: {
281
+ enabled: true,
282
+ transport: resourceTransport,
283
+ allowUpload: true,
284
+ allowPicker: true,
285
+ maxSelected: 5,
286
+ },
287
+ }),
288
+ );
289
+ ```
290
+
291
+ Supported uploads are TXT, Markdown, CSV, JSON, and PDF. The orchestrator
292
+ accepts at most ten resource references per request. Storage buckets and object
293
+ paths are never included in chat requests.
294
+
295
+ | Field | Type / values | Required | What it does |
296
+ |---|---|---:|---|
297
+ | `resources.enabled` | `boolean` | yes | Enables the resource APIs and UI capability. |
298
+ | `resources.transport` | `ConversationResourceTransport` | yes unless supplied to the constructor | Performs authenticated upload, list, attach, and detach operations. |
299
+ | `resources.allowUpload` | `boolean` | no | Shows upload controls in the stock React UI. |
300
+ | `resources.allowPicker` | `boolean` | no | Shows the recent private resource picker. |
301
+ | `resources.acceptedMimeTypes` | file input accept string | no | Narrows the browser file picker. |
302
+ | `resources.maxSelected` | integer from 1 to 10 | no | Limits attachments selected for a conversation. |
303
+
304
+ Custom shells can call `listResources()`, `uploadResource()`,
305
+ `listResourceAttachments()`, `attachResource()`, and `detachResource()` on the
306
+ client. Pass selected references through `sendMessage(message, {
307
+ resourceReferences })`.
308
+
253
309
  ### Orchestrator Config
254
310
 
255
311
  `orchestrator.baseUrl` should point to the orchestrator root URL, not `/v2/chat`. The client appends `/v2/chat` internally.
256
312
 
257
313
  | Field | Type / values | Required | What it does | Example |
258
314
  |---|---|---:|---|---|
259
- | `orchestrator.baseUrl` | URL string | yes | Base URL for the orchestrator. | `https://ai.tagit.live` |
315
+ | `orchestrator.baseUrl` | URL string | yes | Base URL for the request path. In browser code, use your application's same-origin origin. | `window.location.origin` |
260
316
  | `orchestrator.useCaseId` | string | yes | Runtime use case ID to execute. | `uc-default-1lji40` |
261
- | `orchestrator.apiKey` | string | no | Optional API key sent as `X-Api-Key`. | `import.meta.env.VITE_TAGIT_AI_ORCHESTRATOR_API_KEY` |
317
+ | `orchestrator.apiKey` | string | no | Server-only API key sent as `X-Api-Key`. Do not set it in browser-delivered code. | `process.env.KNOTIV_ORCHESTRATOR_API_KEY` |
262
318
  | `orchestrator.snapshotId` | string | no | Pins the client to a specific orchestration snapshot. | `snapshot_2026_04_14` |
263
319
  | `orchestrator.timeoutMs` | positive integer | no | Request timeout in milliseconds. | `30000` |
264
320
  | `orchestrator.maxRetries` | nonnegative integer | no | Number of retry attempts for transient failures. | `3` |
@@ -488,6 +544,56 @@ const transport: OrchestratorTransport = {
488
544
  };
489
545
  ```
490
546
 
547
+ ## Browser integration
548
+
549
+ For a browser application, the supported request path is:
550
+
551
+ ```text
552
+ Browser -> same-origin application route -> Knotiv Orchestrator
553
+ ```
554
+
555
+ The application's route keeps the Knotiv API key on the server and is
556
+ responsible for authenticating its user, authorizing the Agent, accepting only
557
+ approved runtime context, and proxying the normal or streamed response. The
558
+ browser should configure `baseUrl` as `window.location.origin` and should not
559
+ set `orchestrator.apiKey`.
560
+
561
+ For local Vite development, a proxy can make the local application route look
562
+ same-origin while the proxy adds the server-only key. This is a development
563
+ convenience, not a production credential boundary:
564
+
565
+ ```ts
566
+ // vite.config.ts
567
+ import { defineConfig, loadEnv } from 'vite';
568
+
569
+ export default defineConfig(({ mode }) => {
570
+ const env = loadEnv(mode, process.cwd(), '');
571
+
572
+ return {
573
+ server: {
574
+ proxy: {
575
+ '/v2': {
576
+ target: env.KNOTIV_ORCHESTRATOR_BASE_URL,
577
+ changeOrigin: true,
578
+ headers: {
579
+ 'X-Api-Key': env.KNOTIV_ORCHESTRATOR_API_KEY,
580
+ },
581
+ },
582
+ },
583
+ },
584
+ };
585
+ });
586
+ ```
587
+
588
+ Keep `KNOTIV_ORCHESTRATOR_API_KEY` in `.env.local` or another server-only
589
+ secret store. Do not prefix it with `VITE_`.
590
+
591
+ For production, implement an authenticated same-origin route that fixes the
592
+ permitted Agent and user identity on the server, validates incoming runtime
593
+ context, and forwards the response stream. The [AI Client guide](https://knotiv.gitbook.io/knotiv/embed-and-integrate/ai-client)
594
+ includes a Next.js route example. If you enable conversation history, provide
595
+ authenticated `/v2/conversations` routes too.
596
+
491
597
  ## Related Package
492
598
 
493
599
  If you want the full embeddable React widget, install:
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AgentListUpdateOptions, AgentListUpdateResult, AgentOption, ClientConfig, ClientEventListener, ConversationHistoryCreateOptions, ConversationHistoryListOptions, ConversationHistoryListResult, ConversationHistoryLifecycleOptions, ConversationHistoryLoadOptions, ConversationHistoryMessagesResult, ConversationHistoryTransport, ConversationHistoryUpdateOptions, ConversationSummary, ConversationState, SendMessageOptions } from './types.js';
1
+ import type { AgentListUpdateOptions, AgentListUpdateResult, AgentOption, ClientConfig, ClientEventListener, ConversationHistoryCreateOptions, ConversationHistoryListOptions, ConversationHistoryListResult, ConversationHistoryLifecycleOptions, ConversationHistoryLoadOptions, ConversationHistoryMessagesResult, ConversationHistoryTransport, ConversationResource, ConversationResourceReference, ConversationResourceTransport, ConversationResourceUpload, ConversationHistoryUpdateOptions, ConversationSummary, ConversationState, SendMessageOptions } from './types.js';
2
2
  import { type OrchestratorTransport } from './transport.js';
3
3
  /**
4
4
  * Headless AI client core
@@ -12,11 +12,13 @@ export declare class AIClient {
12
12
  private abortReason;
13
13
  private transport;
14
14
  private conversationHistoryTransport;
15
+ private conversationResourceTransport;
15
16
  private createdConversationIds;
16
17
  private activeAgentGeneration;
17
18
  constructor(config: ClientConfig, options?: {
18
19
  transport?: OrchestratorTransport;
19
20
  conversationHistoryTransport?: ConversationHistoryTransport;
21
+ conversationResourceTransport?: ConversationResourceTransport;
20
22
  });
21
23
  private resolveConfiguredDefaultAgentId;
22
24
  private cloneAgent;
@@ -40,6 +42,21 @@ export declare class AIClient {
40
42
  allowDelete: boolean;
41
43
  allowRestore: boolean;
42
44
  };
45
+ getConversationResourceCapabilities(): {
46
+ enabled: boolean;
47
+ allowUpload: boolean;
48
+ allowPicker: boolean;
49
+ allowDelete: boolean;
50
+ acceptedMimeTypes: string;
51
+ maxSelected: number;
52
+ };
53
+ private requireConversationResourceTransport;
54
+ listResources(): Promise<ConversationResource[]>;
55
+ uploadResource(input: ConversationResourceUpload): Promise<ConversationResource>;
56
+ deleteResource(resourceId: string): Promise<void>;
57
+ listResourceAttachments(conversationId?: string): Promise<ConversationResourceReference[]>;
58
+ attachResource(resourceId: string, conversationId?: string): Promise<ConversationResourceReference>;
59
+ detachResource(resourceId: string, conversationId?: string): Promise<void>;
43
60
  /**
44
61
  * Subscribe to client events
45
62
  */
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,qBAAqB,EACrB,WAAW,EAGX,YAAY,EAEZ,mBAAmB,EACnB,gCAAgC,EAChC,8BAA8B,EAC9B,6BAA6B,EAC7B,mCAAmC,EACnC,8BAA8B,EAC9B,iCAAiC,EACjC,4BAA4B,EAC5B,oBAAoB,EACpB,6BAA6B,EAC7B,6BAA6B,EAC7B,0BAA0B,EAC1B,gCAAgC,EAChC,mBAAmB,EACnB,iBAAiB,EAMjB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AA+CxB;;;GAGG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,4BAA4B,CAA6C;IACjF,OAAO,CAAC,6BAA6B,CAA8C;IACnF,OAAO,CAAC,sBAAsB,CAA0B;IACxD,OAAO,CAAC,qBAAqB,CAAK;gBAGhC,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,qBAAqB,CAAC;QAClC,4BAA4B,CAAC,EAAE,4BAA4B,CAAC;QAC5D,6BAA6B,CAAC,EAAE,6BAA6B,CAAC;KAC/D;IA6BH,OAAO,CAAC,+BAA+B;IASvC,OAAO,CAAC,UAAU;IAIlB,SAAS,IAAI,WAAW,EAAE;IAU1B,mBAAmB,IAAI,OAAO;IAI9B,cAAc,IAAI,WAAW;IAU7B,OAAO,CAAC,qBAAqB;IAc7B,OAAO,CAAC,aAAa;IA+BrB,OAAO,CAAC,uBAAuB;IAQ/B,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW;IAY3C,YAAY,CACV,MAAM,EAAE,WAAW,EAAE,EACrB,OAAO,GAAE,sBAA2B,GACnC,qBAAqB;IAoDxB,OAAO,CAAC,wCAAwC;IAQhD;;OAEG;IACH,QAAQ,IAAI,iBAAiB;IAI7B,kCAAkC;;;;;;;IAWlC,mCAAmC;;;;;;;;IAgBnC,OAAO,CAAC,oCAAoC;IAY5C,aAAa,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAIhD,cAAc,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAIhF,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAajD,uBAAuB,CACrB,cAAc,SAA+B,GAC5C,OAAO,CAAC,6BAA6B,EAAE,CAAC;IAI3C,cAAc,CACZ,UAAU,EAAE,MAAM,EAClB,cAAc,SAA+B,GAC5C,OAAO,CAAC,6BAA6B,CAAC;IAIzC,cAAc,CACZ,UAAU,EAAE,MAAM,EAClB,cAAc,SAA+B,GAC5C,OAAO,CAAC,IAAI,CAAC;IAIhB;;OAEG;IACH,EAAE,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI;IAO7C;;OAEG;IACH,OAAO,CAAC,IAAI;IAUZ;;OAEG;IACH,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,oBAAoB;IAwB5B,aAAa,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC,GAAG,MAAM;IAwBnE,qBAAqB,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,GAAG,MAAM;IASnF,OAAO,CAAC,6BAA6B;IAoBrC,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,sBAAsB;IAc9B,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,sBAAsB;YAahB,kBAAkB;YA2DlB,+BAA+B;IA6B7C,OAAO,CAAC,mCAAmC;IAoB3C,2BAA2B,IAAI,OAAO;IAItC,mBAAmB,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,GAAG,gBAAgB,CAAC,GAAG;QACpF,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;KACvB;IAYD;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAmB5B;;OAEG;IACG,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,IAAI,CAAC;YAwEF,uBAAuB;IAwDrC;;OAEG;YACW,cAAc;IA+M5B;;OAEG;YACW,WAAW;YAsIX,gBAAgB;IA6B9B,OAAO,CAAC,sBAAsB;IAsB9B;;;;OAIG;YACW,mBAAmB;IA6BjC,OAAO,CAAC,uBAAuB;IAM/B,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,oBAAoB;IAwB5B,OAAO,CAAC,oBAAoB;YA0Bd,0BAA0B;IA2CxC,OAAO,CAAC,oBAAoB;IAuD5B,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,oBAAoB;IAkC5B,OAAO,CAAC,8BAA8B;IAYtC,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,cAAc;IAgCtB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,mBAAmB;IA+C3B;;OAEG;YACW,kBAAkB;IAkEhC;;OAEG;IACH,MAAM,IAAI,IAAI;IAUd;;;OAGG;IACH,YAAY,IAAI,IAAI;IA4BpB;;;;OAIG;IACG,oBAAoB,CAAC,OAAO,CAAC,EAAE,gCAAgC,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IA8BrG,iBAAiB,CAAC,OAAO,CAAC,EAAE,8BAA8B,GAAG,OAAO,CAAC,6BAA6B,CAAC;IAYnG,gBAAgB,CACpB,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,8BAA8B,GACvC,OAAO,CAAC,iCAAiC,GAAG;QAAE,YAAY,EAAE,mBAAmB,CAAA;KAAE,CAAC;IA4C/E,kBAAkB,CACtB,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,IAAI,CAAC,gCAAgC,EAAE,QAAQ,GAAG,WAAW,CAAC,GACvE,OAAO,CAAC,mBAAmB,CAAC;IAazB,mBAAmB,CACvB,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,mCAAmC,GAC5C,OAAO,CAAC,mBAAmB,CAAC;IAQzB,kBAAkB,CACtB,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,mCAAmC,GAC5C,OAAO,CAAC,mBAAmB,CAAC;IAQzB,mBAAmB,CACvB,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,mCAAmC,GAC5C,OAAO,CAAC,mBAAmB,CAAC;IAQ/B;;;;;OAKG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAWpD;AAED,eAAe,QAAQ,CAAC"}
package/dist/client.js CHANGED
@@ -8,6 +8,32 @@ import { StreamSession } from './stream-session.js';
8
8
  function generateId() {
9
9
  return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
10
10
  }
11
+ function resolveLifecycleErrorResponse(errorBody) {
12
+ try {
13
+ const payload = JSON.parse(errorBody);
14
+ const errorCode = typeof payload.error?.code === 'string'
15
+ ? payload.error.code
16
+ : typeof payload.code === 'string'
17
+ ? payload.code
18
+ : undefined;
19
+ if (errorCode === 'use_case_inactive') {
20
+ return {
21
+ errorCode,
22
+ safeMessage: 'This agent is currently disabled. Ask an authorized operator to enable it before trying again.',
23
+ };
24
+ }
25
+ if (errorCode === 'use_case_archived') {
26
+ return {
27
+ errorCode,
28
+ safeMessage: 'This agent is archived and cannot receive new requests.',
29
+ };
30
+ }
31
+ return { errorCode };
32
+ }
33
+ catch {
34
+ return {};
35
+ }
36
+ }
11
37
  /**
12
38
  * Headless AI client core
13
39
  * Handles orchestrator communication, streaming, and conversation state
@@ -56,6 +82,12 @@ export class AIClient {
56
82
  writable: true,
57
83
  value: null
58
84
  });
85
+ Object.defineProperty(this, "conversationResourceTransport", {
86
+ enumerable: true,
87
+ configurable: true,
88
+ writable: true,
89
+ value: null
90
+ });
59
91
  Object.defineProperty(this, "createdConversationIds", {
60
92
  enumerable: true,
61
93
  configurable: true,
@@ -76,6 +108,8 @@ export class AIClient {
76
108
  (this.config.conversationHistory?.enabled
77
109
  ? new FetchConversationHistoryTransport(this.buildConversationHistoryTransportContext())
78
110
  : null);
111
+ this.conversationResourceTransport =
112
+ options?.conversationResourceTransport ?? this.config.resources?.transport ?? null;
79
113
  const initialUseCaseId = this.resolveConfiguredDefaultAgentId(this.config);
80
114
  this.config.orchestrator.useCaseId = initialUseCaseId;
81
115
  const initialConversationId = this.config.conversation?.conversationId?.trim() ||
@@ -246,6 +280,57 @@ export class AIClient {
246
280
  allowRestore: history?.allowRestore !== false,
247
281
  };
248
282
  }
283
+ getConversationResourceCapabilities() {
284
+ const resources = this.config.resources;
285
+ return {
286
+ enabled: resources?.enabled === true && this.conversationResourceTransport !== null,
287
+ allowUpload: resources?.allowUpload !== false,
288
+ allowPicker: resources?.allowPicker !== false,
289
+ allowDelete: resources?.allowDelete === true &&
290
+ typeof this.conversationResourceTransport?.deleteResource === 'function',
291
+ acceptedMimeTypes: resources?.acceptedMimeTypes ||
292
+ 'text/plain,text/markdown,text/csv,application/json,application/pdf',
293
+ maxSelected: Math.min(10, Math.max(1, resources?.maxSelected ?? 10)),
294
+ };
295
+ }
296
+ requireConversationResourceTransport() {
297
+ if (!this.config.resources?.enabled || !this.conversationResourceTransport) {
298
+ throw this.createError({
299
+ code: 'CONFIG_ERROR',
300
+ message: 'Conversation resources require resources.enabled and an authenticated transport',
301
+ safeMessage: 'Resource workspace is not configured.',
302
+ retryable: false,
303
+ });
304
+ }
305
+ return this.conversationResourceTransport;
306
+ }
307
+ listResources() {
308
+ return this.requireConversationResourceTransport().listResources();
309
+ }
310
+ uploadResource(input) {
311
+ return this.requireConversationResourceTransport().uploadResource(input);
312
+ }
313
+ deleteResource(resourceId) {
314
+ const transport = this.requireConversationResourceTransport();
315
+ if (!transport.deleteResource) {
316
+ throw this.createError({
317
+ code: 'CONFIG_ERROR',
318
+ message: 'Conversation resource deletion requires transport.deleteResource',
319
+ safeMessage: 'File deletion is not configured.',
320
+ retryable: false,
321
+ });
322
+ }
323
+ return transport.deleteResource(resourceId);
324
+ }
325
+ listResourceAttachments(conversationId = this.resolveConversationId()) {
326
+ return this.requireConversationResourceTransport().listAttachments(conversationId);
327
+ }
328
+ attachResource(resourceId, conversationId = this.resolveConversationId()) {
329
+ return this.requireConversationResourceTransport().attachResource(conversationId, resourceId);
330
+ }
331
+ detachResource(resourceId, conversationId = this.resolveConversationId()) {
332
+ return this.requireConversationResourceTransport().detachResource(conversationId, resourceId);
333
+ }
249
334
  /**
250
335
  * Subscribe to client events
251
336
  */
@@ -541,6 +626,10 @@ export class AIClient {
541
626
  role: 'user',
542
627
  content: this.truncateMessage('user', userMessage),
543
628
  timestamp: Date.now(),
629
+ resourceReferences: resolvedOptions?.resourceReferences?.map((reference) => ({
630
+ ...reference,
631
+ resource: reference.resource ? { ...reference.resource } : undefined,
632
+ })),
544
633
  };
545
634
  this.conversationState.messages.push(userMsg);
546
635
  this.checkAndTrimHistory();
@@ -673,6 +762,13 @@ export class AIClient {
673
762
  if (options?.expectedRevision !== undefined) {
674
763
  request.expected_revision = options.expectedRevision;
675
764
  }
765
+ if (options?.resourceReferences?.length) {
766
+ request.resource_references = options.resourceReferences.map((reference) => ({
767
+ schemaVersion: 'conversation_resource_reference.v1',
768
+ resourceId: reference.resourceId,
769
+ purpose: 'attachment',
770
+ }));
771
+ }
676
772
  if (options?.tools) {
677
773
  request.tools = options.tools;
678
774
  }
@@ -710,13 +806,20 @@ export class AIClient {
710
806
  if (!response.ok) {
711
807
  const error = await response.text().catch(() => 'Unknown error');
712
808
  const retryable = response.status >= 500 || response.status === 429;
809
+ const lifecycleError = resolveLifecycleErrorResponse(error);
713
810
  throw this.createError({
714
811
  code: 'REQUEST_FAILED',
715
812
  message: `Orchestrator error (${response.status}): ${error}`,
716
- safeMessage: `Request failed with status ${response.status}.`,
813
+ safeMessage: lifecycleError.safeMessage ??
814
+ `Request failed with status ${response.status}.`,
717
815
  retryable,
718
816
  statusCode: response.status,
719
- details: { responseBody: error },
817
+ details: {
818
+ responseBody: error,
819
+ ...(lifecycleError.errorCode
820
+ ? { orchestratorErrorCode: lifecycleError.errorCode }
821
+ : {}),
822
+ },
720
823
  });
721
824
  }
722
825
  this.emit({ type: 'streaming_started' });