@collective-intelligence/external-apps-server-sdk 0.1.8 → 0.1.10
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 +150 -0
- package/dist/admin.d.ts +423 -25
- package/dist/express.d.ts +20 -3
- package/dist/gateway/contracts.d.ts +20 -3
- package/dist/gateway.d.ts +20 -3
- package/dist/gateway.js +2 -1
- package/dist/index.d.ts +113 -1
- package/dist/index.js +3 -3
- package/dist/knowledge-sources/payload.d.ts +28 -3
- package/dist/knowledge-sources/strapi.d.ts +28 -3
- package/dist/persistence/drizzle.d.ts +42 -3
- package/dist/persistence/drizzle.js +4 -3
- package/dist/resources.d.ts +50 -6
- package/dist/resources.js +3 -3
- package/dist/runtime/effect.d.ts +105 -6
- package/dist/runtime/effect.js +4 -3
- package/dist/runtime/express.d.ts +20 -3
- package/dist/runtime/nestjs.d.ts +48 -6
- package/dist/runtime/nestjs.js +1 -1
- package/dist/runtime/next.d.ts +48 -6
- package/dist/runtime/next.js +1 -1
- package/dist/runtime/web.d.ts +20 -3
- package/dist/runtime/web.js +1 -1
- package/dist/tools/ai-sdk.js +2 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -358,6 +358,34 @@ than waiting for a workflow in this bounded tool adapter. The
|
|
|
358
358
|
shows distinct receipts and final results, independent resource authorization,
|
|
359
359
|
and application-owned execution, recovery, failure, and duplicate protection.
|
|
360
360
|
|
|
361
|
+
## Workflow results
|
|
362
|
+
|
|
363
|
+
Workflow invocation returns `runId`. A successful declared-output Workflow run
|
|
364
|
+
read through `runs.get` has `result: { nativeStatus: "completed", output }`;
|
|
365
|
+
the `completed` event from `runs.stream` carries that same object in `data`.
|
|
366
|
+
CI reads the validated, persisted Workflow output snapshot. The Gateway Tool's
|
|
367
|
+
response becomes public only through the Workflow's explicit `outputContract`
|
|
368
|
+
bindings and schema; selecting a Tool alone does not declare a Workflow result.
|
|
369
|
+
See the [binding example and lifecycle](../../../docs/architecture/external-app-gateway.md#workflow-results-and-observation).
|
|
370
|
+
|
|
371
|
+
The native worker finishes and persists output independently of the browser.
|
|
372
|
+
External terminal publication stays lazy on the next authorized run read, with
|
|
373
|
+
status, result and completion event committed together as an immutable receipt.
|
|
374
|
+
Existing terminal results and cancellation decisions survive repeated reads.
|
|
375
|
+
Owner-user/kind, Organization, Application and external audit-subject checks
|
|
376
|
+
still apply to both snapshots and events.
|
|
377
|
+
|
|
378
|
+
If reading fails, observe the original `runId` again; do not resubmit the
|
|
379
|
+
business command to retrieve its result. The browser SDK's `runs.follow`
|
|
380
|
+
returns an event page, propagates read failures, and does not retry them
|
|
381
|
+
automatically. Missing promised output is a technical invariant defect, not a
|
|
382
|
+
normal null-output or partial-success terminal result. There is no historical
|
|
383
|
+
terminal-run backfill or compatibility mode for this contract.
|
|
384
|
+
|
|
385
|
+
Keep analysis history and candidate results in Knowledge reads. Send a matching
|
|
386
|
+
completion notification only after the matching results are actually available
|
|
387
|
+
in Knowledge, even if the command run has already completed.
|
|
388
|
+
|
|
361
389
|
## Agent runs and conversations
|
|
362
390
|
|
|
363
391
|
`agents.invoke({ agentId, input })` starts one Agent run and returns
|
|
@@ -517,6 +545,113 @@ const created = await ci.members.createOrGet({
|
|
|
517
545
|
- Only `temporarily_unavailable` is retryable (the client retries it); a
|
|
518
546
|
creation CI refuses is a non-retryable `internal_error`.
|
|
519
547
|
|
|
548
|
+
## Durable files
|
|
549
|
+
|
|
550
|
+
A confidential application stores a file that a workflow run reads later, such
|
|
551
|
+
as the PDF of a signed form. The file is a private stored file of the
|
|
552
|
+
Organization the credentials were authorized for, with no expiry.
|
|
553
|
+
|
|
554
|
+
```ts
|
|
555
|
+
const uploaded = await ci.files.upload({
|
|
556
|
+
contentBase64: pdf.toString("base64"),
|
|
557
|
+
contentType: "application/pdf",
|
|
558
|
+
fileName: "application.pdf",
|
|
559
|
+
organizationId,
|
|
560
|
+
sizeBytes: pdf.byteLength
|
|
561
|
+
})
|
|
562
|
+
// uploaded.value.result: { storageFileId }
|
|
563
|
+
|
|
564
|
+
await ci.workflows.invoke({
|
|
565
|
+
input: { document: { storageFileId: uploaded.value.result.storageFileId } },
|
|
566
|
+
organizationId,
|
|
567
|
+
workflowFqn
|
|
568
|
+
})
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
- `contentType` is `application/pdf`, `image/jpeg` or `image/png`, and the file
|
|
572
|
+
holds 1 byte to 10 MiB. `sizeBytes` must match the decoded content. Other
|
|
573
|
+
files are refused with `invalid_request`.
|
|
574
|
+
- A workflow input can name the `storageFileId`; the nodes of a run of the same
|
|
575
|
+
Organization read the file through their stored file access. The file has no
|
|
576
|
+
public URL, and another Organization cannot read it.
|
|
577
|
+
- `attachments.upload` is different: its file belongs to one run and expires
|
|
578
|
+
after 24 hours.
|
|
579
|
+
- It needs the `ai:attachments` scope. Only service credentials may call it: a
|
|
580
|
+
delegated user token or an anonymous visitor gets `operation_not_allowed`.
|
|
581
|
+
|
|
582
|
+
### Entity File fields
|
|
583
|
+
|
|
584
|
+
A File field of an entity schema takes a different flow: the file becomes a
|
|
585
|
+
File value of the entity, not a stored file a workflow reads.
|
|
586
|
+
`resources.createUpload` asks CI for a single-use upload slot, the server PUTs
|
|
587
|
+
the bytes straight to storage, and the entity write through CI's resources API
|
|
588
|
+
names the slot's `uploadId` as `{ upload }` for that File field key:
|
|
589
|
+
|
|
590
|
+
```ts
|
|
591
|
+
const slot = await ci.resources.createUpload({
|
|
592
|
+
field: "memberLogo",
|
|
593
|
+
filename: "logo.png",
|
|
594
|
+
mimeType: "image/png",
|
|
595
|
+
organizationId,
|
|
596
|
+
schemaId: "apito.vetrina.schemas.member-company"
|
|
597
|
+
})
|
|
598
|
+
if (slot.ok) {
|
|
599
|
+
const { headers, method, uploadId, url } = slot.value.result
|
|
600
|
+
await fetch(url, { body: logo, headers, method })
|
|
601
|
+
// The entity write then sends { memberLogo: { upload: uploadId } }.
|
|
602
|
+
}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
- Two credentials can ask for a slot, as for entity writes: the member's
|
|
606
|
+
delegated token (`exchangeMemberSession`), writing as that member; or the
|
|
607
|
+
application's service credential, for schemas declared by the application's
|
|
608
|
+
own package only, writing as the Organization default service principal.
|
|
609
|
+
`schemaId` is the schema id or FQN.
|
|
610
|
+
- A refusal resolves `{ ok: false, error }` with CI's `correlationId` and a
|
|
611
|
+
`code`; `upload_not_supported` means the Organization storage cannot presign
|
|
612
|
+
uploads. Only `retryable` failures are retried.
|
|
613
|
+
- Each attempt, request and response body, is bounded by `timeoutMs`
|
|
614
|
+
(10 seconds by default); a CI that stops answering ends in a retryable
|
|
615
|
+
`unavailable`. `signal` cancels: a cancelled request rejects with the
|
|
616
|
+
signal's reason.
|
|
617
|
+
- The PUT is the caller's: send exactly `headers` to `url` with `method`. No
|
|
618
|
+
file bytes pass through CI's API. A slot is single use: the first successful
|
|
619
|
+
write consumes it; request a new one to retry.
|
|
620
|
+
- The write form of a File field key is `{ upload }` to add the uploaded file,
|
|
621
|
+
`{ id }` (or a File value read before) to keep a file, an ordered array for a
|
|
622
|
+
multiple field, or `null` to remove every file. Omit the key to keep its
|
|
623
|
+
files.
|
|
624
|
+
- `/runtime/effect` exports the Effect schemas `EntityFileValue` (a File value
|
|
625
|
+
as CI reads return it), `EntityFileWrite` (one file of a write) and
|
|
626
|
+
`EntityFileFieldWrite` (the write form of a File field key). Their types
|
|
627
|
+
equal the client SDK types of the same name. They validate CI entity
|
|
628
|
+
values; a portable resource form has no File field, so
|
|
629
|
+
`projectResourceSchema` refuses them.
|
|
630
|
+
|
|
631
|
+
## Runtime origin
|
|
632
|
+
|
|
633
|
+
The browser origins of an Organization are the `allowedOrigins` that its
|
|
634
|
+
installed applications declare, plus one runtime origin per application. A
|
|
635
|
+
confidential application sets its runtime origin, for example the URL of each
|
|
636
|
+
new deployment; CI keeps storage CORS in line with the Organization origins, so
|
|
637
|
+
a browser on that origin can upload to a presigned storage URL.
|
|
638
|
+
|
|
639
|
+
```ts
|
|
640
|
+
await ci.origins.setRuntime({
|
|
641
|
+
organizationId,
|
|
642
|
+
origin: `https://${process.env.VERCEL_URL}`
|
|
643
|
+
})
|
|
644
|
+
// value.result: { origin }
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
- Each call replaces the application's previous runtime origin, so the list
|
|
648
|
+
does not grow; declare stable origins, such as the production site, in
|
|
649
|
+
`allowedOrigins`.
|
|
650
|
+
- `origin` is an exact HTTPS origin (`https://host[:port]`, no path), or a
|
|
651
|
+
loopback HTTP origin with a port; other values get `invalid_request`.
|
|
652
|
+
- It needs the `origins:write` scope. Only service credentials may call it: a
|
|
653
|
+
delegated user token or an anonymous visitor gets `operation_not_allowed`.
|
|
654
|
+
|
|
520
655
|
## Member company links
|
|
521
656
|
|
|
522
657
|
An application links a member of its Organization to the Knowledge company
|
|
@@ -1407,6 +1542,21 @@ The adapter never retries or follows redirects. Cancellation or a lost response
|
|
|
1407
1542
|
after dispatch remains an uncertain outcome; retain the original action for
|
|
1408
1543
|
explicit resubmission.
|
|
1409
1544
|
|
|
1545
|
+
#### File uploads through the BFF
|
|
1546
|
+
|
|
1547
|
+
When the definition declares `capabilities.upload: true`, the handler also
|
|
1548
|
+
accepts `POST {basePath}/uploads` with `{ field, filename, mimeType }`. It calls
|
|
1549
|
+
`authorize` with the operation `upload`, then forwards the request with the
|
|
1550
|
+
verified grant to `/application/v1/resources/{schemaFqn}/uploads`. CI answers
|
|
1551
|
+
the File upload `{ uploadId, url, method: "PUT", headers }`; the browser PUTs
|
|
1552
|
+
the bytes straight to that storage URL, so no file bytes pass through the BFF.
|
|
1553
|
+
The entity write that names `{ upload: uploadId }` follows the normal update
|
|
1554
|
+
path. `upload_not_supported` (the Organization storage can not presign) maps to
|
|
1555
|
+
HTTP 400. Without the capability the request answers `capability_not_supported`
|
|
1556
|
+
and is not forwarded. A local `defineEntityResource` binding answers
|
|
1557
|
+
`capability_not_supported`, and a `defineCrudResource` handler answers 404 for
|
|
1558
|
+
this path. The client SDK README documents the write form.
|
|
1559
|
+
|
|
1410
1560
|
## Optional local user authentication
|
|
1411
1561
|
|
|
1412
1562
|
Import `createBetterAuth` only from
|