@oberik/sdk 0.1.0 → 0.2.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.
- package/dist/cjs/index.js +322 -35
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.d.ts +443 -69
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +319 -34
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.d.ts
CHANGED
|
@@ -82,6 +82,8 @@ export interface ClientOptions {
|
|
|
82
82
|
headers?: Record<string, string>;
|
|
83
83
|
/** Client-side tools registered up-front; auto-dispatched by chat.run/stream. */
|
|
84
84
|
tools?: ClientToolDef[];
|
|
85
|
+
/** UI components the agent can draw into your app. Needs the `ui_tools` capability. */
|
|
86
|
+
ui?: UiComponent<any>[];
|
|
85
87
|
}
|
|
86
88
|
/** Public tenant view — never includes the API key. */
|
|
87
89
|
export interface TenantOut {
|
|
@@ -540,10 +542,86 @@ export interface QuestionAnswer {
|
|
|
540
542
|
}
|
|
541
543
|
/** Answer a batch of questions. Return one entry per question (or a single
|
|
542
544
|
* `{ chat_instead: true }` to decline the whole batch and keep chatting). */
|
|
545
|
+
/** An Agent Plugin visible to this token: what the project published, plus anything
|
|
546
|
+
* this end-user uploaded. */
|
|
547
|
+
export interface PublishedPlugin {
|
|
548
|
+
id: string;
|
|
549
|
+
name: string;
|
|
550
|
+
version?: string | null;
|
|
551
|
+
description: string;
|
|
552
|
+
/** `tenant` = published by the project to everyone; `private` = this user's own. */
|
|
553
|
+
visibility: string;
|
|
554
|
+
owner_subject?: string | null;
|
|
555
|
+
enabled: boolean;
|
|
556
|
+
size_bytes: number;
|
|
557
|
+
/** Each skill's name and description are all the agent sees until it loads one, so
|
|
558
|
+
* the description is the line that decides whether a procedure ever gets used. */
|
|
559
|
+
skills: {
|
|
560
|
+
name: string;
|
|
561
|
+
description: string;
|
|
562
|
+
files: string[];
|
|
563
|
+
}[];
|
|
564
|
+
mcp_servers: string[];
|
|
565
|
+
/** Wrong but not fatal — a skill that would not parse, a server that was refused.
|
|
566
|
+
* Worth surfacing: a plugin whose skill silently did not load is the failure people
|
|
567
|
+
* spend an afternoon on. */
|
|
568
|
+
warnings: string[];
|
|
569
|
+
}
|
|
570
|
+
/** A component your app can render, declared for the agent to call.
|
|
571
|
+
*
|
|
572
|
+
* The difference from a client tool is that there is no result. A client tool is work
|
|
573
|
+
* handed back — the turn stops, you run it, the answer returns. This is a one-way
|
|
574
|
+
* instruction: the agent calls it, your `render` runs, and the turn carries straight
|
|
575
|
+
* on. Use it wherever showing beats describing. */
|
|
576
|
+
export interface UiComponent<A = Record<string, unknown>> {
|
|
577
|
+
name: string;
|
|
578
|
+
/** What it shows, and when the agent should reach for it. The agent picks from this,
|
|
579
|
+
* so "Draw a line chart of a numeric series over time" beats "chart". */
|
|
580
|
+
description: string;
|
|
581
|
+
/** JSON Schema for the arguments, exactly as a client tool declares them. */
|
|
582
|
+
parameters?: Record<string, unknown>;
|
|
583
|
+
/** Called when the agent draws it. Return nothing — anything you return is dropped,
|
|
584
|
+
* because the agent is not waiting. */
|
|
585
|
+
render: (args: A) => void;
|
|
586
|
+
}
|
|
587
|
+
/** One thing the agent drew, as it comes back on the turn. */
|
|
588
|
+
export interface UiRender {
|
|
589
|
+
name: string;
|
|
590
|
+
args: Record<string, unknown>;
|
|
591
|
+
}
|
|
592
|
+
/** Something the agent stopped to ask permission for.
|
|
593
|
+
*
|
|
594
|
+
* Arrives with `requires_action` and an EMPTY `tool_calls`: an approval is not the
|
|
595
|
+
* client's work to execute, so tool auto-dispatch can never grant one on the user's
|
|
596
|
+
* behalf. It has to reach a person. */
|
|
597
|
+
export interface PendingApproval {
|
|
598
|
+
tool_call_id: string;
|
|
599
|
+
/** One line saying exactly what the agent will do, with the specifics in it. */
|
|
600
|
+
action: string;
|
|
601
|
+
/** What the person needs in order to decide — the message, the command, the rows. */
|
|
602
|
+
detail?: string | null;
|
|
603
|
+
/** What cannot easily be undone. Usually the only part that decides the answer. */
|
|
604
|
+
consequence?: string | null;
|
|
605
|
+
}
|
|
606
|
+
/** A person's answer to one approval pause. */
|
|
607
|
+
export interface ApprovalDecision {
|
|
608
|
+
tool_call_id?: string;
|
|
609
|
+
approved: boolean;
|
|
610
|
+
/** The difference between "no" and "no, use the other address". */
|
|
611
|
+
note?: string | null;
|
|
612
|
+
}
|
|
613
|
+
/** Put the request to a person and return their decision.
|
|
614
|
+
*
|
|
615
|
+
* Throwing, or returning `false`, is a refusal — and a refusal stops the work: the
|
|
616
|
+
* agent is told not to try another way and to ask what you want instead. */
|
|
617
|
+
export type ApprovalHandler = (request: PendingApproval) => ApprovalDecision | boolean | Promise<ApprovalDecision | boolean>;
|
|
543
618
|
export type QuestionHandler = (pending: PendingQuestions) => QuestionAnswer | QuestionAnswerItem[] | Promise<QuestionAnswer | QuestionAnswerItem[]>;
|
|
544
619
|
export interface RunOptions extends Omit<ChatRequest, "tool_results" | "client_tools"> {
|
|
545
620
|
/** Extra client tools for this call (merged over any registered on the client). */
|
|
546
621
|
tools?: ClientToolDef[];
|
|
622
|
+
/** UI components for this call (merged over any registered on the client). Needs the
|
|
623
|
+
* `ui_tools` capability. */
|
|
624
|
+
ui?: UiComponent<any>[];
|
|
547
625
|
/** Max auto tool-dispatch rounds before giving up (default 10). */
|
|
548
626
|
maxToolRounds?: number;
|
|
549
627
|
/** Fires before each batch of client tools is executed. */
|
|
@@ -551,10 +629,24 @@ export interface RunOptions extends Omit<ChatRequest, "tool_results" | "client_t
|
|
|
551
629
|
/** Answer the agent's questions and continue the turn automatically. Without it,
|
|
552
630
|
* `run` returns as soon as the agent asks, with `questions` set. */
|
|
553
631
|
onQuestion?: QuestionHandler;
|
|
632
|
+
/** Decide the agent's approval requests and continue the turn. Without it, `run`
|
|
633
|
+
* returns as soon as the agent asks, with `approvals` set — which is the right
|
|
634
|
+
* default: nothing should be able to approve an irreversible action by accident. */
|
|
635
|
+
onApproval?: ApprovalHandler;
|
|
554
636
|
signal?: AbortSignal;
|
|
555
637
|
}
|
|
556
|
-
/** A non-text input part
|
|
557
|
-
*
|
|
638
|
+
/** A non-text input part. `url` is a data: URI or an https URL.
|
|
639
|
+
*
|
|
640
|
+
* Two capabilities decide what happens to it, and they are separate on purpose:
|
|
641
|
+
*
|
|
642
|
+
* - `input:file` accepts ANY attachment — a PNG and a WAV included. What the model
|
|
643
|
+
* cannot perceive is read as text instead (OCR for a scan, a transcript, an
|
|
644
|
+
* extraction), so granting it costs fidelity, never access.
|
|
645
|
+
* - `input:image` / `input:audio` / `input:video` additionally let the model look at
|
|
646
|
+
* that kind with its own senses, raw.
|
|
647
|
+
*
|
|
648
|
+
* So a project that just wants users to attach whatever they have grants `input:file`;
|
|
649
|
+
* one that wants the model to actually SEE the picture grants `input:image` too. */
|
|
558
650
|
export interface Attachment {
|
|
559
651
|
/** Stable identity, set on anything the agent produced. Match on this, not on `url`:
|
|
560
652
|
* a URL is signed per response, so the same file arrives with a different one from
|
|
@@ -623,14 +715,39 @@ export interface ChatRequest {
|
|
|
623
715
|
messages?: string[] | null;
|
|
624
716
|
/** Multimodal inputs (images/audio/video/files) for this turn. */
|
|
625
717
|
attachments?: Attachment[] | null;
|
|
626
|
-
/** Modalities the
|
|
627
|
-
* output:<modality
|
|
718
|
+
/** Modalities the MODEL may generate this turn, e.g. ["text","image"]. Bounded by the
|
|
719
|
+
* token's `output:<modality>` capabilities; ignored by text-only models.
|
|
720
|
+
*
|
|
721
|
+
* Nothing to do with what the agent may hand over as a file: a screenshot it took or
|
|
722
|
+
* a chart it rendered in a sandbox is a file it produced, not a modality it emitted,
|
|
723
|
+
* and `output:file` is what permits sending those — any of them, pictures included. */
|
|
628
724
|
output_modalities?: string[] | null;
|
|
629
725
|
tool_results?: ClientToolResult[] | null;
|
|
630
726
|
/** Resume a turn paused on `ask_user`. The wording the agent reads is composed
|
|
631
727
|
* server-side from the question it actually asked, so the transcript can't drift
|
|
632
728
|
* from what was on screen. */
|
|
633
729
|
question_answers?: QuestionAnswer[] | null;
|
|
730
|
+
/** UI components the agent may draw this turn. `chat.run`/`chat.stream` fill this in
|
|
731
|
+
* from the components you registered — set it directly only on a raw `/chat` call. */
|
|
732
|
+
ui_tools?: Record<string, unknown>[] | null;
|
|
733
|
+
/** Answers to approval pauses, resuming the turn. */
|
|
734
|
+
approval_decisions?: ApprovalDecision[] | null;
|
|
735
|
+
/** Let the agent stop and ask permission before an action with consequences. Needs
|
|
736
|
+
* the `approvals` capability. Set false for any caller that cannot answer — a batch
|
|
737
|
+
* job, a webhook — so the agent never stalls waiting on a decision. */
|
|
738
|
+
enable_approvals?: boolean;
|
|
739
|
+
/** Let the agent reach for the skills published to this project. Needs the `plugins`
|
|
740
|
+
* capability. */
|
|
741
|
+
/** Let the agent call the tools this project publishes as URLs — Oberik POSTs to
|
|
742
|
+
* the customer's endpoint with the end-user's identity signed into the body. Needs
|
|
743
|
+
* the `webhook_tools` capability. Turn it off for a turn that should not touch your
|
|
744
|
+
* systems. */
|
|
745
|
+
enable_webhook_tools?: boolean;
|
|
746
|
+
enable_plugins?: boolean;
|
|
747
|
+
/** Which plugins this turn may use, by name. Omit for everything the token can see.
|
|
748
|
+
* Narrowing only — a name that is not visible is absent rather than an error, so a
|
|
749
|
+
* pinned list does not start failing turns the day someone deletes one. */
|
|
750
|
+
plugins?: string[] | null;
|
|
634
751
|
/** The user pressed Done on a page the agent handed them. Resumes a turn that
|
|
635
752
|
* stopped on a blocking hand-off — the button IS the answer, so nothing else is
|
|
636
753
|
* needed with it. */
|
|
@@ -662,7 +779,6 @@ export interface ChatRequest {
|
|
|
662
779
|
* Omitted = the sandbox bound to this chat session, else a fresh one. */
|
|
663
780
|
computer_session_id?: string | null;
|
|
664
781
|
/** Let the agent run read-only SQL against connected query-mode data sources. */
|
|
665
|
-
enable_data_query?: boolean;
|
|
666
782
|
/** Let the agent drive a real browser — click, type, scroll, wait, capture — rather
|
|
667
783
|
* than fetching one page at a time. Needs the `browser` capability and the browser
|
|
668
784
|
* service; `web_search`/`browse_url` work without it. */
|
|
@@ -701,10 +817,9 @@ export interface Citation {
|
|
|
701
817
|
quote: string | null;
|
|
702
818
|
}
|
|
703
819
|
/** A unified source for UI rendering (clickable pill) — a document citation, a
|
|
704
|
-
* web result/page
|
|
705
|
-
* (query sources carry the executed SQL in `snippet` for verifiability). */
|
|
820
|
+
* web result/page. `type` = "document" | "web". */
|
|
706
821
|
export interface Source {
|
|
707
|
-
type: "document" | "web" |
|
|
822
|
+
type: "document" | "web" | string;
|
|
708
823
|
title?: string | null;
|
|
709
824
|
url?: string | null;
|
|
710
825
|
snippet?: string | null;
|
|
@@ -723,6 +838,10 @@ export interface ChatResponse {
|
|
|
723
838
|
* auto-dispatch can never answer it on the user's behalf. Resume by sending
|
|
724
839
|
* `question_answers` (or let `chat.run`/`chat.stream` do it via `onQuestion`). */
|
|
725
840
|
questions: PendingQuestions[];
|
|
841
|
+
/** The agent stopped before doing something and is waiting to be allowed. Same shape
|
|
842
|
+
* of pause as `questions`, and likewise never in `tool_calls`. Resume by sending
|
|
843
|
+
* `approval_decisions` (or let `chat.run`/`chat.stream` do it via `onApproval`). */
|
|
844
|
+
approvals: PendingApproval[];
|
|
726
845
|
/** The agent's plan for this session, when the todo family ran this turn. */
|
|
727
846
|
todos: TodoItem[];
|
|
728
847
|
/** Every subagent of this conversation, including ones still working — a turn ending
|
|
@@ -735,6 +854,10 @@ export interface ChatResponse {
|
|
|
735
854
|
/** Non-text outputs of the turn: generated media, and files the agent exported
|
|
736
855
|
* from its sandbox. `url` is signed fresh per response — don't persist it. */
|
|
737
856
|
attachments: Attachment[];
|
|
857
|
+
/** Components the agent drew this turn, in call order. `chat.run`/`chat.stream` have
|
|
858
|
+
* already called each component's `render` by the time you see this; it is here so a
|
|
859
|
+
* client that re-mounts can redraw from the list. */
|
|
860
|
+
ui: UiRender[];
|
|
738
861
|
/** Guardrail actions taken this turn, e.g. "pii:EMAIL", "ungrounded", "injection". */
|
|
739
862
|
guard_flags: string[];
|
|
740
863
|
/** A reasoning model's thinking for this turn, else "". Live only — it is not stored
|
|
@@ -797,42 +920,63 @@ export interface TaskOut {
|
|
|
797
920
|
last_error: string | null;
|
|
798
921
|
created_at: string;
|
|
799
922
|
}
|
|
800
|
-
|
|
801
|
-
|
|
923
|
+
/** What a project key may do. An admin key satisfies a mint requirement, never the
|
|
924
|
+
* reverse. */
|
|
925
|
+
export type ProjectKeyScope = "admin" | "mint";
|
|
926
|
+
export interface ProjectKeyInfo {
|
|
927
|
+
id: string;
|
|
802
928
|
name: string;
|
|
803
|
-
|
|
804
|
-
/**
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
929
|
+
scope: ProjectKeyScope;
|
|
930
|
+
/** The visible stub, e.g. "pk_ab12…". The key itself is shown once, at creation. */
|
|
931
|
+
prefix: string;
|
|
932
|
+
lastUsedAt: string | null;
|
|
933
|
+
createdAt: string;
|
|
934
|
+
}
|
|
935
|
+
/** What a token holds, and which per-turn switches are worth setting on it. */
|
|
936
|
+
export interface TokenCapabilities {
|
|
937
|
+
subject: string;
|
|
938
|
+
scope: string;
|
|
939
|
+
/** `null` = unrestricted (a service key), which is NOT the same as an empty list. */
|
|
940
|
+
capabilities: string[] | null;
|
|
941
|
+
flags: {
|
|
942
|
+
flag: string;
|
|
943
|
+
/** Any one of these is enough to grant it. Empty = ungated. */
|
|
944
|
+
capability: string[];
|
|
945
|
+
granted: boolean;
|
|
946
|
+
platform_enabled: boolean;
|
|
947
|
+
/** Whether setting this flag on a request would change anything. */
|
|
948
|
+
effective: boolean;
|
|
949
|
+
label: string;
|
|
950
|
+
description: string;
|
|
951
|
+
group: string | null;
|
|
952
|
+
}[];
|
|
953
|
+
modalities: {
|
|
954
|
+
/** What may be attached. */
|
|
955
|
+
input: string[];
|
|
956
|
+
/** What the model perceives directly; the rest arrives as extracted text. */
|
|
957
|
+
native: string[];
|
|
958
|
+
/** What the agent may hand back. */
|
|
959
|
+
output: string[];
|
|
960
|
+
};
|
|
961
|
+
limits: {
|
|
962
|
+
max_effort: string | null;
|
|
963
|
+
max_tool_iterations: number | null;
|
|
964
|
+
max_context_tokens: number | null;
|
|
965
|
+
};
|
|
819
966
|
}
|
|
820
|
-
|
|
967
|
+
/** One memory or wiki page. */
|
|
968
|
+
export interface KnowledgeItem {
|
|
821
969
|
id: string;
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
config_keys: string[];
|
|
827
|
-
sync_interval_seconds: number;
|
|
828
|
-
tags: string[];
|
|
970
|
+
kind: "memory" | "wiki" | string;
|
|
971
|
+
title?: string | null;
|
|
972
|
+
text: string;
|
|
973
|
+
owner_subject?: string | null;
|
|
829
974
|
visibility: string;
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
created_at: string;
|
|
975
|
+
/** Documents a wiki page was written from. */
|
|
976
|
+
source_document_ids: string[];
|
|
977
|
+
written_at?: string | null;
|
|
978
|
+
/** True once a source document changed or went away — the page is unverified. */
|
|
979
|
+
stale?: boolean;
|
|
836
980
|
}
|
|
837
981
|
export interface AuditEntry {
|
|
838
982
|
id: string;
|
|
@@ -960,6 +1104,19 @@ export type StreamEvent = {
|
|
|
960
1104
|
questions: PendingQuestions[];
|
|
961
1105
|
};
|
|
962
1106
|
}
|
|
1107
|
+
/** The agent is waiting to be allowed to do something. Render it and answer — nothing
|
|
1108
|
+
* proceeds until you do. */
|
|
1109
|
+
| {
|
|
1110
|
+
event: "approvals";
|
|
1111
|
+
data: {
|
|
1112
|
+
approvals: PendingApproval[];
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
/** The agent drew something. Arrives the instant it is called, mid-turn. */
|
|
1116
|
+
| {
|
|
1117
|
+
event: "ui";
|
|
1118
|
+
data: UiRender;
|
|
1119
|
+
}
|
|
963
1120
|
/** The agent has handed a page to the user — open a viewer, poll `browserFrame`
|
|
964
1121
|
* and relay clicks with `browserInput`. It then asks a question and waits. */
|
|
965
1122
|
| {
|
|
@@ -991,6 +1148,8 @@ export type StreamEvent = {
|
|
|
991
1148
|
requires_action: boolean;
|
|
992
1149
|
tool_calls: PendingToolCall[];
|
|
993
1150
|
questions: PendingQuestions[];
|
|
1151
|
+
approvals: PendingApproval[];
|
|
1152
|
+
ui: UiRender[];
|
|
994
1153
|
todos: TodoItem[];
|
|
995
1154
|
subagents: SubagentState[];
|
|
996
1155
|
handoff?: Handoff | null;
|
|
@@ -1046,6 +1205,10 @@ export interface StreamHandlers {
|
|
|
1046
1205
|
* cannot leave the panel wrong. One that is `running` after the turn ends is still
|
|
1047
1206
|
* running — keep showing it, and it will report into the next turn. */
|
|
1048
1207
|
onSubagents?: (subagents: SubagentState[]) => void;
|
|
1208
|
+
/** UI components the agent may draw, for this stream. Their `render` is called for
|
|
1209
|
+
* you as each arrives; this fires alongside if you also want to observe them. */
|
|
1210
|
+
ui?: UiComponent<any>[];
|
|
1211
|
+
onUi?: (render: UiRender) => void;
|
|
1049
1212
|
/** A sandbox command's output as it is produced. Append it to a live pane keyed by
|
|
1050
1213
|
* `command_id` — a long build should look like it is working, and a person watching
|
|
1051
1214
|
* needs to be able to tell a slow command from a stuck one. */
|
|
@@ -1075,6 +1238,9 @@ export interface StreamHandlers {
|
|
|
1075
1238
|
* picker, resolve with what the user chose (or `{ chat_instead: true }` if they
|
|
1076
1239
|
* would rather keep talking), and `done` resolves only once the agent finishes. */
|
|
1077
1240
|
onQuestion?: QuestionHandler;
|
|
1241
|
+
/** Decide the agent's approval requests and continue the stream. Without it the
|
|
1242
|
+
* stream ends with `approvals` on `done` and you resume it yourself. */
|
|
1243
|
+
onApproval?: ApprovalHandler;
|
|
1078
1244
|
/** Called each time the client (re)connects, with the resume attempt count. */
|
|
1079
1245
|
onReconnect?: (attempt: number) => void;
|
|
1080
1246
|
signal?: AbortSignal;
|
|
@@ -1118,6 +1284,10 @@ export interface ChatDone {
|
|
|
1118
1284
|
tool_calls: PendingToolCall[];
|
|
1119
1285
|
/** Questions the agent paused on. Empty once `onQuestion` has answered them. */
|
|
1120
1286
|
questions: PendingQuestions[];
|
|
1287
|
+
/** Approvals the agent is waiting on. Empty once `onApproval` has decided them. */
|
|
1288
|
+
approvals: PendingApproval[];
|
|
1289
|
+
/** Components the agent drew this turn, in call order. Already rendered by then. */
|
|
1290
|
+
ui: UiRender[];
|
|
1121
1291
|
/** The agent's plan for this session, when the todo family ran this turn. */
|
|
1122
1292
|
todos: TodoItem[];
|
|
1123
1293
|
/** Every subagent of the conversation. Some may still be `running` — the turn
|
|
@@ -1208,6 +1378,7 @@ export declare class AgentFramework {
|
|
|
1208
1378
|
private readonly opts;
|
|
1209
1379
|
private readonly _fetch;
|
|
1210
1380
|
private readonly toolRegistry;
|
|
1381
|
+
private readonly uiRegistry;
|
|
1211
1382
|
/** Active session watchers, so a streamed turn can mark its own messages seen. */
|
|
1212
1383
|
private readonly watchers;
|
|
1213
1384
|
/** The bearer in use: `opts.token` initially, replaced on refresh. */
|
|
@@ -1253,8 +1424,20 @@ export declare class AgentFramework {
|
|
|
1253
1424
|
/** Register a client-side tool (handler run when the agent calls it). */
|
|
1254
1425
|
registerTool(tool: ClientToolDef): this;
|
|
1255
1426
|
registerTools(tools: ClientToolDef[]): this;
|
|
1427
|
+
/** Register a UI component the agent can draw into your app.
|
|
1428
|
+
*
|
|
1429
|
+
* Unlike a tool, nothing is handed back: the agent calls it, your `render` runs, and
|
|
1430
|
+
* the turn carries on without waiting. */
|
|
1431
|
+
registerUi(component: UiComponent<any>): this;
|
|
1432
|
+
registerUiComponents(components: UiComponent<any>[]): this;
|
|
1256
1433
|
/** Merge the client-level registry with any per-call tools (per-call wins). */
|
|
1257
1434
|
private resolveTools;
|
|
1435
|
+
private resolveUi;
|
|
1436
|
+
/** Draw whatever the agent asked for, in order.
|
|
1437
|
+
*
|
|
1438
|
+
* A component that throws is logged and skipped: one broken chart must not take down
|
|
1439
|
+
* the turn that drew it, and there is nothing to report back to the agent anyway. */
|
|
1440
|
+
private renderUi;
|
|
1258
1441
|
/** `bearer` overrides token resolution — used to replay a request with the token a
|
|
1259
1442
|
* refresh just produced, instead of asking for one again. */
|
|
1260
1443
|
private authHeaders;
|
|
@@ -1448,6 +1631,42 @@ export declare class AgentFramework {
|
|
|
1448
1631
|
}) => Promise<SessionOut>;
|
|
1449
1632
|
};
|
|
1450
1633
|
};
|
|
1634
|
+
/** Agent Plugins — the skills this token can reach for, and the ones it may add.
|
|
1635
|
+
*
|
|
1636
|
+
* Two sources, one list: what the project published plus anything this end-user
|
|
1637
|
+
* uploaded. Uploading needs the `plugins:write` capability; reading does not, because
|
|
1638
|
+
* a project that publishes a procedure wants its agent to use it. */
|
|
1639
|
+
plugins: {
|
|
1640
|
+
list: () => Promise<PublishedPlugin[]>;
|
|
1641
|
+
delete: (id: string) => Promise<void>;
|
|
1642
|
+
/** Publish a skill. Re-uploading a name replaces it.
|
|
1643
|
+
*
|
|
1644
|
+
* Takes whatever the customer actually has:
|
|
1645
|
+
*
|
|
1646
|
+
* - a packaged Agent Plugin (`plugin.json` + `skills/`), read as-is;
|
|
1647
|
+
* - a zipped folder of skills, or a single `SKILL.md` — a manifest is written
|
|
1648
|
+
* for them, because requiring one to publish a file of instructions is a
|
|
1649
|
+
* packaging exercise standing in front of the feature;
|
|
1650
|
+
* - a folder's files, from a directory picker, each keyed by its relative path.
|
|
1651
|
+
*
|
|
1652
|
+
* An end-user's plugin is private to them and unioned on top of the project's —
|
|
1653
|
+
* only a project key can publish to everyone. */
|
|
1654
|
+
upload: (file: UploadInput, opts?: {
|
|
1655
|
+
filename?: string;
|
|
1656
|
+
signal?: AbortSignal;
|
|
1657
|
+
}) => Promise<PublishedPlugin>;
|
|
1658
|
+
/** Publish a folder of skills without zipping it.
|
|
1659
|
+
*
|
|
1660
|
+
* `files` is what a browser directory picker gives you. Each part is sent under
|
|
1661
|
+
* its path relative to the folder, which is all the server needs to lay the
|
|
1662
|
+
* skills out — so no zip library is needed on your side. */
|
|
1663
|
+
uploadFolder: (files: {
|
|
1664
|
+
path: string;
|
|
1665
|
+
content: UploadInput;
|
|
1666
|
+
}[], opts?: {
|
|
1667
|
+
signal?: AbortSignal;
|
|
1668
|
+
}) => Promise<PublishedPlugin>;
|
|
1669
|
+
};
|
|
1451
1670
|
documents: {
|
|
1452
1671
|
list: (query?: {
|
|
1453
1672
|
tag?: string;
|
|
@@ -1509,26 +1728,35 @@ export declare class AgentFramework {
|
|
|
1509
1728
|
get: (id: string) => Promise<TaskOut>;
|
|
1510
1729
|
cancel: (id: string) => Promise<TaskOut>;
|
|
1511
1730
|
};
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
}) => Promise<SourceOut>;
|
|
1528
|
-
/** Trigger a sync now; pass `fullRefresh` to re-pull everything. */
|
|
1529
|
-
sync: (id: string, fullRefresh?: boolean) => Promise<SourceOut>;
|
|
1530
|
-
remove: (id: string) => Promise<void>;
|
|
1731
|
+
/**
|
|
1732
|
+
* What the agent wrote down — remembered facts and wiki pages.
|
|
1733
|
+
*
|
|
1734
|
+
* Retrieval reads these back on every turn, so when an answer looks wrong a
|
|
1735
|
+
* remembered fact is often the reason. The ACL that governs retrieval governs this
|
|
1736
|
+
* too: a caller sees exactly what its token could have retrieved.
|
|
1737
|
+
*/
|
|
1738
|
+
memory: {
|
|
1739
|
+
/** `kind` is "memory" (facts, per end-user) or "wiki" (pages, per user or shared). */
|
|
1740
|
+
list: (opts?: {
|
|
1741
|
+
kind?: "memory" | "wiki";
|
|
1742
|
+
limit?: number;
|
|
1743
|
+
}) => Promise<KnowledgeItem[]>;
|
|
1744
|
+
/** Forget one. The agent can write it again; this removes what is there now. */
|
|
1745
|
+
delete: (itemId: string) => Promise<void>;
|
|
1531
1746
|
};
|
|
1747
|
+
/**
|
|
1748
|
+
* What this token can actually do.
|
|
1749
|
+
*
|
|
1750
|
+
* The three gates on a turn are the platform's kill switch, the token's capability
|
|
1751
|
+
* and the per-request `enable_*` flag, and until this existed a client could read
|
|
1752
|
+
* none of them. `flags[].effective` is the useful one: false means setting that flag
|
|
1753
|
+
* changes nothing on this token — which is otherwise indistinguishable from the agent
|
|
1754
|
+
* simply choosing not to use the tool.
|
|
1755
|
+
*
|
|
1756
|
+
* Cheap and safe to call on load: a token asking what it holds is reading its own
|
|
1757
|
+
* claims back, so it needs no capability of its own.
|
|
1758
|
+
*/
|
|
1759
|
+
capabilities: () => Promise<TokenCapabilities>;
|
|
1532
1760
|
audit: {
|
|
1533
1761
|
/** Read the tenant's audit trail (admin). Filter by action/subject. */
|
|
1534
1762
|
list: (opts?: {
|
|
@@ -1588,16 +1816,6 @@ export declare class AgentFramework {
|
|
|
1588
1816
|
/** Pull a file out of the sandbox as bytes. */
|
|
1589
1817
|
download: (id: string, path: string) => Promise<Blob>;
|
|
1590
1818
|
};
|
|
1591
|
-
/**
|
|
1592
|
-
* Connect an external data source and keep it live in the agent's knowledge.
|
|
1593
|
-
* Validates the connector, runs an initial sync, and (when an interval is set)
|
|
1594
|
-
* schedules recurring auto-refresh so the data never goes stale.
|
|
1595
|
-
*
|
|
1596
|
-
* await ai.sync({ name: "orders", connector_type: "postgres",
|
|
1597
|
-
* config: { dsn, query: "select id, status, total from orders",
|
|
1598
|
-
* cursor_column: "updated_at" }, sync_interval_seconds: 900 });
|
|
1599
|
-
*/
|
|
1600
|
-
sync: (config: SyncConfig) => Promise<SourceOut>;
|
|
1601
1819
|
private runWithTools;
|
|
1602
1820
|
/** Wrap startStream so a `done` carrying `requires_action` auto-executes the
|
|
1603
1821
|
* client tools and continues the stream (same session) until the agent ends. */
|
|
@@ -1608,6 +1826,162 @@ export declare class AgentFramework {
|
|
|
1608
1826
|
private multipartUpload;
|
|
1609
1827
|
private rangedDownload;
|
|
1610
1828
|
}
|
|
1829
|
+
/** Where projects are administered and end-user tokens are minted. A different host
|
|
1830
|
+
* from {@link DEFAULT_BASE_URL}, and a different credential — the two are not
|
|
1831
|
+
* interchangeable, which is the whole reason there are two clients. */
|
|
1832
|
+
export declare const DEFAULT_CONTROL_PLANE_URL = "https://oberik.com";
|
|
1833
|
+
export interface ProjectClientOptions {
|
|
1834
|
+
/** From the project's URL in the dashboard. */
|
|
1835
|
+
projectId: string;
|
|
1836
|
+
/** `pk_…`. Server-side only — see the constructor. */
|
|
1837
|
+
projectKey: string;
|
|
1838
|
+
/** Only for a self-hosted control plane. */
|
|
1839
|
+
baseUrl?: string;
|
|
1840
|
+
fetch?: typeof fetch;
|
|
1841
|
+
}
|
|
1842
|
+
export interface MintTokenInput {
|
|
1843
|
+
/** Who this token is. Owns whatever it creates, and is the default visibility
|
|
1844
|
+
* boundary. A hierarchical path: `acme:finance:ana`. */
|
|
1845
|
+
subject: string;
|
|
1846
|
+
/** What it may SEE — a prefix of `subject`. Omit for "only its own data". */
|
|
1847
|
+
scope?: string;
|
|
1848
|
+
/** What it may DO. Intersected with the project's ceiling: you can narrow, never
|
|
1849
|
+
* widen. Omit and the token carries everything the project allows. */
|
|
1850
|
+
capabilities?: string[];
|
|
1851
|
+
roles?: string[];
|
|
1852
|
+
groups?: string[];
|
|
1853
|
+
/** Restrict this token to a subset of the project's models. */
|
|
1854
|
+
models?: string[];
|
|
1855
|
+
maxEffort?: "minimal" | "low" | "medium" | "high";
|
|
1856
|
+
/** Ceiling on agent↔tool loops. Unset means unlimited. */
|
|
1857
|
+
maxToolIterations?: number;
|
|
1858
|
+
maxContextTokens?: number;
|
|
1859
|
+
/** Seconds. Keep it short and mint per session. */
|
|
1860
|
+
expiresIn?: number;
|
|
1861
|
+
}
|
|
1862
|
+
export interface MintedToken {
|
|
1863
|
+
access_token: string;
|
|
1864
|
+
token_type: string;
|
|
1865
|
+
expires_in: number;
|
|
1866
|
+
tenant_id: string;
|
|
1867
|
+
/** What was ACTUALLY granted. Compare with what you asked for to see what the
|
|
1868
|
+
* project's ceiling trimmed — a capability you expected and did not get is a
|
|
1869
|
+
* toggle in the dashboard, not a bug in your code. */
|
|
1870
|
+
capabilities: string[];
|
|
1871
|
+
scope: string | null;
|
|
1872
|
+
allowed_models: string[] | null;
|
|
1873
|
+
max_effort: string | null;
|
|
1874
|
+
max_context_tokens: number | null;
|
|
1875
|
+
}
|
|
1876
|
+
/**
|
|
1877
|
+
* The control plane, from your backend.
|
|
1878
|
+
*
|
|
1879
|
+
* The other client in this package talks to the data plane as one end-user. This one
|
|
1880
|
+
* holds the project key and administers the project itself: minting those tokens,
|
|
1881
|
+
* setting the capability ceiling, curating the corpus.
|
|
1882
|
+
*
|
|
1883
|
+
* They are separate classes on purpose. A project key can mint a token with any
|
|
1884
|
+
* capability the project allows — and create further keys, and delete the project — so
|
|
1885
|
+
* it must never travel to the same place an end-user token does. Two types make that a
|
|
1886
|
+
* decision someone has to make rather than a field they can accidentally set.
|
|
1887
|
+
*/
|
|
1888
|
+
export declare class OberikProject {
|
|
1889
|
+
readonly baseUrl: string;
|
|
1890
|
+
private readonly projectId;
|
|
1891
|
+
private readonly key;
|
|
1892
|
+
private readonly _fetch;
|
|
1893
|
+
constructor(opts: ProjectClientOptions);
|
|
1894
|
+
private request;
|
|
1895
|
+
tokens: {
|
|
1896
|
+
/**
|
|
1897
|
+
* Mint a short-lived token for ONE end-user.
|
|
1898
|
+
*
|
|
1899
|
+
* const { access_token } = await oberik.tokens.mint({
|
|
1900
|
+
* subject: `${user.orgId}:${user.id}`,
|
|
1901
|
+
* scope: `${user.orgId}:${user.id}`,
|
|
1902
|
+
* capabilities: ["chat", "documents:read"],
|
|
1903
|
+
* });
|
|
1904
|
+
*/
|
|
1905
|
+
mint: (input: MintTokenInput) => Promise<MintedToken>;
|
|
1906
|
+
/**
|
|
1907
|
+
* The same thing shaped as the callback {@link createClient} wants, so the two
|
|
1908
|
+
* halves of this package fit together without a wrapper:
|
|
1909
|
+
*
|
|
1910
|
+
* const ai = createClient({ getToken: oberik.tokens.forUser({ subject: id }) });
|
|
1911
|
+
*
|
|
1912
|
+
* Called again whenever a token expires, so the client refreshes on its own.
|
|
1913
|
+
*/
|
|
1914
|
+
forUser: (input: MintTokenInput) => () => Promise<string>;
|
|
1915
|
+
};
|
|
1916
|
+
/** The capability ceiling: the maximum any token minted here may hold. */
|
|
1917
|
+
capabilities: {
|
|
1918
|
+
get: () => Promise<Record<string, unknown>>;
|
|
1919
|
+
/** Merges — send only what you want to change. */
|
|
1920
|
+
set: (caps: Record<string, unknown>) => Promise<unknown>;
|
|
1921
|
+
};
|
|
1922
|
+
/** Documents owned by the project rather than by any one end-user: the corpus you
|
|
1923
|
+
* curate and your users only read. */
|
|
1924
|
+
documents: {
|
|
1925
|
+
list: () => Promise<unknown[]>;
|
|
1926
|
+
upload: (file: Blob | File, opts?: {
|
|
1927
|
+
filename?: string;
|
|
1928
|
+
tags?: string[];
|
|
1929
|
+
}) => Promise<unknown>;
|
|
1930
|
+
delete: (documentId: string) => Promise<void>;
|
|
1931
|
+
};
|
|
1932
|
+
/** Prepended to every request for this project, above anything a caller sends. */
|
|
1933
|
+
systemPrompt: {
|
|
1934
|
+
set: (systemPrompt: string) => Promise<unknown>;
|
|
1935
|
+
};
|
|
1936
|
+
/** Browser origins allowed to call the data plane with this project's tokens. */
|
|
1937
|
+
origins: {
|
|
1938
|
+
set: (origins: string[]) => Promise<unknown>;
|
|
1939
|
+
};
|
|
1940
|
+
/** Tools the agent calls by URL. The signing secret comes back once, on create. */
|
|
1941
|
+
webhookTools: {
|
|
1942
|
+
list: () => Promise<unknown[]>;
|
|
1943
|
+
create: (tool: {
|
|
1944
|
+
name: string;
|
|
1945
|
+
description: string;
|
|
1946
|
+
url: string;
|
|
1947
|
+
parameters?: Record<string, unknown>;
|
|
1948
|
+
headers?: Record<string, string>;
|
|
1949
|
+
}) => Promise<{
|
|
1950
|
+
id: string;
|
|
1951
|
+
secret: string;
|
|
1952
|
+
}>;
|
|
1953
|
+
delete: (toolId: string) => Promise<void>;
|
|
1954
|
+
};
|
|
1955
|
+
/** Server-side keys. A created one is returned once and never again. */
|
|
1956
|
+
/**
|
|
1957
|
+
* Further project keys.
|
|
1958
|
+
*
|
|
1959
|
+
* `scope` is the important argument and it defaults to the narrow one. A `mint` key
|
|
1960
|
+
* can turn your signed-in user into an end-user token and nothing else — it cannot
|
|
1961
|
+
* read the corpus, raise the capability ceiling, issue more keys, or delete the
|
|
1962
|
+
* project. That is what almost every backend actually needs, and it is the difference
|
|
1963
|
+
* between a leaked key costing you some tokens and costing you the workspace.
|
|
1964
|
+
*/
|
|
1965
|
+
keys: {
|
|
1966
|
+
list: () => Promise<ProjectKeyInfo[]>;
|
|
1967
|
+
create: (name: string, opts?: {
|
|
1968
|
+
scope?: ProjectKeyScope;
|
|
1969
|
+
}) => Promise<{
|
|
1970
|
+
id: string;
|
|
1971
|
+
key: string;
|
|
1972
|
+
scope: ProjectKeyScope;
|
|
1973
|
+
}>;
|
|
1974
|
+
revoke: (keyId: string) => Promise<void>;
|
|
1975
|
+
};
|
|
1976
|
+
/** Spend, requests, tokens and latency — including per end-user, since spend is
|
|
1977
|
+
* attributed to the token's subject. */
|
|
1978
|
+
usage: {
|
|
1979
|
+
summary: () => Promise<unknown>;
|
|
1980
|
+
observability: (windowSeconds?: number) => Promise<unknown>;
|
|
1981
|
+
};
|
|
1982
|
+
}
|
|
1983
|
+
/** Factory helper for the server-side client. */
|
|
1984
|
+
export declare function createProjectClient(opts: ProjectClientOptions): OberikProject;
|
|
1611
1985
|
/** Factory helper. */
|
|
1612
1986
|
export declare function createClient(opts: ClientOptions): AgentFramework;
|
|
1613
1987
|
export default AgentFramework;
|