@omelhorsite/sdk 0.17.0 → 0.18.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/index.js +527 -19
- package/dist/types/auth/tokens.d.ts +1 -1
- package/dist/types/client.d.ts +3 -0
- package/dist/types/resources/admin/llm.d.ts +34 -0
- package/dist/types/resources/bots.d.ts +394 -0
- package/dist/types/resources/content/news/feeds.d.ts +9 -2
- package/dist/types/resources/content/news/index.d.ts +23 -0
- package/dist/types/resources/content/news/sources.d.ts +61 -5
- package/dist/types/resources/content/notifications.d.ts +1 -1
- package/dist/types/resources/cron.d.ts +303 -26
- package/dist/types/resources/index.d.ts +1 -0
- package/dist/types/resources/search.d.ts +5 -0
- package/dist/types/resources/tools/imageGeneration.d.ts +156 -0
- package/dist/types/resources/tools/index.d.ts +4 -0
- package/package.json +1 -1
|
@@ -93,7 +93,7 @@ export interface TokenStore {
|
|
|
93
93
|
* narrowest set the product actually uses: every extra scope makes the
|
|
94
94
|
* approval page scarier for no benefit.
|
|
95
95
|
*/
|
|
96
|
-
export declare const OMS_SCOPES: readonly ["openid", "profile", "email", "tools:read", "tools:write", "storage:read", "storage:write", "tickets:write", "llm", "blogs:read", "blogs:write", "news:read", "news:write", "cron:read", "cron:write"];
|
|
96
|
+
export declare const OMS_SCOPES: readonly ["openid", "profile", "email", "tools:read", "tools:write", "storage:read", "storage:write", "tickets:write", "llm", "blogs:read", "blogs:write", "news:read", "news:write", "cron:read", "cron:write", "cron:run", "bots:read", "bots:write"];
|
|
97
97
|
/** One of {@link OMS_SCOPES}. */
|
|
98
98
|
export type OmsScope = (typeof OMS_SCOPES)[number];
|
|
99
99
|
/** Refresh this long before the real expiry unless the host says otherwise. */
|
package/dist/types/client.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { AuthSessionsNamespace } from "./resources/auth/sessions";
|
|
|
20
20
|
import { ChestsNamespace } from "./resources/chests";
|
|
21
21
|
import { ContentNamespace } from "./resources/content";
|
|
22
22
|
import { CronNamespace } from "./resources/cron";
|
|
23
|
+
import { BotsNamespace } from "./resources/bots";
|
|
23
24
|
import { DynamicQrsNamespace } from "./resources/dynamicQrs";
|
|
24
25
|
import { FormsNamespace } from "./resources/forms";
|
|
25
26
|
import { IpLookupNamespace } from "./resources/ipLookup";
|
|
@@ -186,6 +187,8 @@ export declare class Oms {
|
|
|
186
187
|
readonly llm: LlmNamespace;
|
|
187
188
|
/** TypeScript scripts the server runs on a schedule as the signed-in person. */
|
|
188
189
|
readonly cron: CronNamespace;
|
|
190
|
+
/** Messaging channels (Telegram bots): contacts, conversations, sending. */
|
|
191
|
+
readonly bots: BotsNamespace;
|
|
189
192
|
/**
|
|
190
193
|
* The WebSocket connection: playback handoff, jams, notifications, job
|
|
191
194
|
* progress. Opens nothing until {@link RealtimeNamespace.connect} is called,
|
|
@@ -100,6 +100,22 @@ export interface LlmProviderTestResult {
|
|
|
100
100
|
readonly latency_ms?: number;
|
|
101
101
|
readonly error?: string;
|
|
102
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* One upstream serving a model on OpenRouter: the same model at a different
|
|
105
|
+
* price and health per real provider. `status` is `0` when healthy and
|
|
106
|
+
* negative while OpenRouter steers traffic away from it.
|
|
107
|
+
*/
|
|
108
|
+
export interface LlmModelEndpoint {
|
|
109
|
+
/** The routing tag, e.g. `"openai/flex"`; what goes in `metadata.routing.order`. */
|
|
110
|
+
readonly tag: string;
|
|
111
|
+
readonly name: string;
|
|
112
|
+
readonly input_price_per_million: number | null;
|
|
113
|
+
readonly output_price_per_million: number | null;
|
|
114
|
+
readonly context_window: number | null;
|
|
115
|
+
readonly max_output_tokens: number | null;
|
|
116
|
+
readonly status: number;
|
|
117
|
+
readonly capabilities: LlmCapabilities;
|
|
118
|
+
}
|
|
103
119
|
export interface TestLlmProviderInput {
|
|
104
120
|
/** A `model_id` of that provider; defaults to its first enabled model. */
|
|
105
121
|
readonly modelId?: string;
|
|
@@ -149,6 +165,13 @@ export interface CreateLlmModelInput {
|
|
|
149
165
|
readonly free?: boolean;
|
|
150
166
|
readonly capabilities?: LlmCapabilities;
|
|
151
167
|
readonly limits?: LlmLimits;
|
|
168
|
+
/**
|
|
169
|
+
* Free-form notes on the model. One key is read: `routing`, the OpenRouter
|
|
170
|
+
* `provider` object sent with every request to this model, for instance
|
|
171
|
+
* `{ order: ["openai/flex"], allow_fallbacks: false }` to pin the cheapest
|
|
172
|
+
* upstream. Pick a tag from {@link AdminLlmProvidersNamespace.modelEndpoints}.
|
|
173
|
+
*/
|
|
174
|
+
readonly metadata?: JsonObject;
|
|
152
175
|
}
|
|
153
176
|
/** The provider and the `model_id` are fixed after creation. */
|
|
154
177
|
export type UpdateLlmModelInput = Partial<Omit<CreateLlmModelInput, "llmProviderId" | "modelId">>;
|
|
@@ -231,6 +254,17 @@ export declare class AdminLlmProvidersNamespace extends Resource {
|
|
|
231
254
|
availableModels(id: Id, input?: {
|
|
232
255
|
fresh?: boolean;
|
|
233
256
|
}, options?: RequestOptions): Promise<LlmAvailableModel[]>;
|
|
257
|
+
/**
|
|
258
|
+
* `GET /admin/llm_providers/:id/model_endpoints` - the upstreams that serve
|
|
259
|
+
* a model on OpenRouter, cheapest first, with their prices. Empty on any
|
|
260
|
+
* other kind of provider. Cached for ten minutes; `fresh` skips the cache.
|
|
261
|
+
*
|
|
262
|
+
* @throws {OmsApiError} 400 without `modelId`; 502 when OpenRouter does not answer.
|
|
263
|
+
*/
|
|
264
|
+
modelEndpoints(id: Id, input: {
|
|
265
|
+
modelId: string;
|
|
266
|
+
fresh?: boolean;
|
|
267
|
+
}, options?: RequestOptions): Promise<LlmModelEndpoint[]>;
|
|
234
268
|
/** One tiny completion, to check the key, the URL and a model. */
|
|
235
269
|
test(id: Id, input?: TestLlmProviderInput, options?: RequestOptions): Promise<LlmProviderTestResult>;
|
|
236
270
|
}
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `bots` namespace: messaging channels (Telegram bots for now), the
|
|
3
|
+
* contacts who talk to them and the conversations, plus sending.
|
|
4
|
+
*
|
|
5
|
+
* A channel is a bot token the account connected; the server validates it,
|
|
6
|
+
* registers a webhook and from then on every message the bot receives lands
|
|
7
|
+
* here as a {@link BotContact} and a {@link BotMessage}. Sending is
|
|
8
|
+
* {@link BotMessagesNamespace.send}: the server talks to Telegram and records
|
|
9
|
+
* the outgoing message with its source, so an inbox shows what went where.
|
|
10
|
+
*
|
|
11
|
+
* Needs the `bots:read` scope to read and `bots:write` to send or connect.
|
|
12
|
+
*/
|
|
13
|
+
import { Resource } from "../http";
|
|
14
|
+
import type { ApiClient } from "../http";
|
|
15
|
+
import type { ListParams } from "../listing";
|
|
16
|
+
import type { Id, Paginated, RequestOptions, Timestamp } from "../types";
|
|
17
|
+
export declare const BOT_CHANNEL_KINDS: readonly ["telegram"];
|
|
18
|
+
export type BotChannelKind = (typeof BOT_CHANNEL_KINDS)[number];
|
|
19
|
+
export declare const BOT_CHANNEL_HEALTHS: readonly ["unknown", "ok", "error"];
|
|
20
|
+
export type BotChannelHealth = (typeof BOT_CHANNEL_HEALTHS)[number];
|
|
21
|
+
/** What the bot does: `inbox` keeps the conversations and lets the API send; `responder` answers on the owner's behalf. */
|
|
22
|
+
export declare const BOT_PLUGINS: readonly ["inbox", "responder"];
|
|
23
|
+
export type BotPlugin = (typeof BOT_PLUGINS)[number];
|
|
24
|
+
/** Telegram's own cap on a message's text. Longer is a `400`. */
|
|
25
|
+
export declare const BOT_MESSAGE_MAX_TEXT = 4096;
|
|
26
|
+
/** A connected bot. The token never comes back: only whether one is stored. */
|
|
27
|
+
export interface BotChannel {
|
|
28
|
+
readonly id: Id;
|
|
29
|
+
readonly created_at: Timestamp;
|
|
30
|
+
readonly updated_at: Timestamp;
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly kind: BotChannelKind;
|
|
33
|
+
readonly plugin: BotPlugin;
|
|
34
|
+
/** The bot's own handle on the platform, filled from the token. */
|
|
35
|
+
readonly username: string | null;
|
|
36
|
+
/** The bot's own id on the platform. */
|
|
37
|
+
readonly external_id: string | null;
|
|
38
|
+
readonly enabled: boolean;
|
|
39
|
+
readonly health: BotChannelHealth;
|
|
40
|
+
readonly last_error: string | null;
|
|
41
|
+
readonly last_message_at: Timestamp | null;
|
|
42
|
+
readonly token_set: boolean;
|
|
43
|
+
/** Where the platform delivers the bot's updates. */
|
|
44
|
+
readonly webhook_url: string;
|
|
45
|
+
}
|
|
46
|
+
/** `GET /bot_channels/:id` adds two counters. */
|
|
47
|
+
export interface BotChannelDetail extends BotChannel {
|
|
48
|
+
readonly contacts_count: number;
|
|
49
|
+
readonly unread_count: number;
|
|
50
|
+
}
|
|
51
|
+
export interface CreateBotChannelInput {
|
|
52
|
+
readonly name: string;
|
|
53
|
+
/** The token the platform's bot factory gave you (Telegram: @BotFather). */
|
|
54
|
+
readonly token: string;
|
|
55
|
+
readonly kind?: BotChannelKind;
|
|
56
|
+
/** Defaults to `inbox`. */
|
|
57
|
+
readonly plugin?: BotPlugin;
|
|
58
|
+
readonly enabled?: boolean;
|
|
59
|
+
}
|
|
60
|
+
/** A new `token` reconnects the channel; omit it to keep the stored one. */
|
|
61
|
+
export type UpdateBotChannelInput = Partial<CreateBotChannelInput>;
|
|
62
|
+
/** What the platform reports about the bot and its webhook. */
|
|
63
|
+
export type BotChannelStatus = {
|
|
64
|
+
readonly ok: true;
|
|
65
|
+
readonly username: string | null;
|
|
66
|
+
readonly webhook_url: string;
|
|
67
|
+
readonly webhook_set: boolean;
|
|
68
|
+
readonly pending_updates: number;
|
|
69
|
+
readonly last_error: string | null;
|
|
70
|
+
} | {
|
|
71
|
+
readonly ok: false;
|
|
72
|
+
readonly error: string;
|
|
73
|
+
};
|
|
74
|
+
export declare const BOT_CHANNEL_FILTER_COLUMNS: readonly ["name", "kind", "enabled"];
|
|
75
|
+
export interface ListBotChannelsParams extends ListParams<(typeof BOT_CHANNEL_FILTER_COLUMNS)[number]> {
|
|
76
|
+
}
|
|
77
|
+
export declare const BOT_CONTACT_KINDS: readonly ["private", "group", "supergroup", "channel"];
|
|
78
|
+
export type BotContactKind = (typeof BOT_CONTACT_KINDS)[number];
|
|
79
|
+
/** Someone (or some group) that talked to a channel. */
|
|
80
|
+
export interface BotContact {
|
|
81
|
+
readonly id: Id;
|
|
82
|
+
readonly created_at: Timestamp;
|
|
83
|
+
readonly updated_at: Timestamp;
|
|
84
|
+
readonly bot_channel_id: Id;
|
|
85
|
+
/** The chat id on the platform. */
|
|
86
|
+
readonly external_id: string;
|
|
87
|
+
readonly kind: BotContactKind;
|
|
88
|
+
readonly name: string | null;
|
|
89
|
+
readonly username: string | null;
|
|
90
|
+
readonly tags: string[];
|
|
91
|
+
/** The contact blocked the bot or left the group: sending is refused. */
|
|
92
|
+
readonly blocked: boolean;
|
|
93
|
+
readonly last_message_at: Timestamp | null;
|
|
94
|
+
readonly last_direction: "in" | "out" | null;
|
|
95
|
+
readonly last_text: string | null;
|
|
96
|
+
readonly messages_count: number;
|
|
97
|
+
readonly unread_count: number;
|
|
98
|
+
/** The responder could not answer; `note` says what was missing. */
|
|
99
|
+
readonly needs_human: boolean;
|
|
100
|
+
readonly note: string | null;
|
|
101
|
+
readonly handled_until: Timestamp | null;
|
|
102
|
+
/** The name, or `@username`, or the chat id. */
|
|
103
|
+
readonly display_name: string;
|
|
104
|
+
}
|
|
105
|
+
export interface UpdateBotContactInput {
|
|
106
|
+
readonly name?: string | null;
|
|
107
|
+
readonly tags?: readonly string[];
|
|
108
|
+
readonly needs_human?: boolean;
|
|
109
|
+
readonly note?: string | null;
|
|
110
|
+
}
|
|
111
|
+
export declare const BOT_CONTACT_FILTER_COLUMNS: readonly ["bot_channel_id", "external_id", "username", "kind", "blocked"];
|
|
112
|
+
export interface ListBotContactsParams extends ListParams<(typeof BOT_CONTACT_FILTER_COLUMNS)[number]> {
|
|
113
|
+
/** Only contacts of one channel. */
|
|
114
|
+
readonly channelId?: Id;
|
|
115
|
+
}
|
|
116
|
+
export type BotMessageDirection = "in" | "out";
|
|
117
|
+
/** `contact` came in; `human` was sent from the inbox; `api` by a token (a script, the CLI); `bot` by the responder. */
|
|
118
|
+
export type BotMessageSource = "contact" | "human" | "api" | "bot";
|
|
119
|
+
export interface BotMessage {
|
|
120
|
+
readonly id: Id;
|
|
121
|
+
readonly created_at: Timestamp;
|
|
122
|
+
readonly updated_at: Timestamp;
|
|
123
|
+
readonly bot_channel_id: Id;
|
|
124
|
+
readonly bot_contact_id: Id;
|
|
125
|
+
readonly direction: BotMessageDirection;
|
|
126
|
+
readonly source: BotMessageSource;
|
|
127
|
+
readonly text: string;
|
|
128
|
+
readonly external_id: string | null;
|
|
129
|
+
readonly sent_at: Timestamp;
|
|
130
|
+
/** Set when the platform refused the send; the row stays so the thread shows it. */
|
|
131
|
+
readonly error: string | null;
|
|
132
|
+
}
|
|
133
|
+
export declare const BOT_MESSAGE_FILTER_COLUMNS: readonly ["bot_channel_id", "bot_contact_id", "direction", "source"];
|
|
134
|
+
export interface ListBotMessagesParams extends ListParams<(typeof BOT_MESSAGE_FILTER_COLUMNS)[number]> {
|
|
135
|
+
readonly contactId?: Id;
|
|
136
|
+
readonly channelId?: Id;
|
|
137
|
+
}
|
|
138
|
+
/** `text` for the text as typed; `html` for Telegram's HTML subset (bold, links, blockquote). */
|
|
139
|
+
export type BotMessageFormat = "text" | "html";
|
|
140
|
+
export type SendBotMessageInput = ({
|
|
141
|
+
readonly contactId: Id;
|
|
142
|
+
readonly channelId?: undefined;
|
|
143
|
+
readonly externalId?: undefined;
|
|
144
|
+
} | {
|
|
145
|
+
/** A contact that has not written yet, by channel and chat id. */
|
|
146
|
+
readonly channelId: Id;
|
|
147
|
+
readonly externalId: string;
|
|
148
|
+
readonly contactId?: undefined;
|
|
149
|
+
}) & {
|
|
150
|
+
readonly text: string;
|
|
151
|
+
readonly format?: BotMessageFormat;
|
|
152
|
+
};
|
|
153
|
+
/** The responder of a channel whose plugin is `responder`. `id` is null until it is first saved. */
|
|
154
|
+
export interface BotResponder {
|
|
155
|
+
readonly id: Id | null;
|
|
156
|
+
readonly created_at: Timestamp | null;
|
|
157
|
+
readonly updated_at: Timestamp | null;
|
|
158
|
+
readonly bot_channel_id: Id;
|
|
159
|
+
readonly enabled: boolean;
|
|
160
|
+
readonly system_prompt: string;
|
|
161
|
+
readonly knowledge: string;
|
|
162
|
+
readonly signature: string;
|
|
163
|
+
/** An LLM model id or model_id; null for the account's default. */
|
|
164
|
+
readonly model: string | null;
|
|
165
|
+
/** Runs per day, at hours drawn inside the window. */
|
|
166
|
+
readonly slots_per_day: number;
|
|
167
|
+
readonly window_start: string;
|
|
168
|
+
readonly window_end: string;
|
|
169
|
+
readonly timezone: string;
|
|
170
|
+
readonly history_limit: number;
|
|
171
|
+
readonly language: string;
|
|
172
|
+
readonly facts_count: number;
|
|
173
|
+
readonly sources_count: number;
|
|
174
|
+
readonly waiting_count: number;
|
|
175
|
+
}
|
|
176
|
+
export type UpdateBotResponderInput = Partial<Pick<BotResponder, "enabled" | "system_prompt" | "knowledge" | "signature" | "model" | "slots_per_day" | "window_start" | "window_end" | "timezone" | "history_limit" | "language">>;
|
|
177
|
+
export type BotFactSource = "manual" | "chat" | "learned";
|
|
178
|
+
export interface BotFact {
|
|
179
|
+
readonly id: Id;
|
|
180
|
+
readonly created_at: Timestamp;
|
|
181
|
+
readonly updated_at: Timestamp;
|
|
182
|
+
readonly bot_channel_id: Id;
|
|
183
|
+
readonly text: string;
|
|
184
|
+
readonly valid_from: string | null;
|
|
185
|
+
readonly valid_until: string | null;
|
|
186
|
+
readonly source: BotFactSource;
|
|
187
|
+
readonly bot_contact_id: Id | null;
|
|
188
|
+
readonly active: boolean;
|
|
189
|
+
}
|
|
190
|
+
export interface CreateBotFactInput {
|
|
191
|
+
readonly channelId: Id;
|
|
192
|
+
readonly text: string;
|
|
193
|
+
readonly valid_from?: string | null;
|
|
194
|
+
readonly valid_until?: string | null;
|
|
195
|
+
}
|
|
196
|
+
export type UpdateBotFactInput = Partial<Omit<CreateBotFactInput, "channelId">>;
|
|
197
|
+
export declare const BOT_FACT_FILTER_COLUMNS: readonly ["bot_channel_id", "source", "bot_contact_id"];
|
|
198
|
+
export interface ListBotFactsParams extends ListParams<(typeof BOT_FACT_FILTER_COLUMNS)[number]> {
|
|
199
|
+
readonly channelId?: Id;
|
|
200
|
+
}
|
|
201
|
+
export interface BotSource {
|
|
202
|
+
readonly id: Id;
|
|
203
|
+
readonly created_at: Timestamp;
|
|
204
|
+
readonly updated_at: Timestamp;
|
|
205
|
+
readonly bot_channel_id: Id;
|
|
206
|
+
readonly name: string;
|
|
207
|
+
readonly url: string;
|
|
208
|
+
readonly description: string | null;
|
|
209
|
+
}
|
|
210
|
+
export interface CreateBotSourceInput {
|
|
211
|
+
readonly channelId: Id;
|
|
212
|
+
readonly name: string;
|
|
213
|
+
readonly url: string;
|
|
214
|
+
readonly description?: string | null;
|
|
215
|
+
}
|
|
216
|
+
export type UpdateBotSourceInput = Partial<Omit<CreateBotSourceInput, "channelId">>;
|
|
217
|
+
export declare const BOT_SOURCE_FILTER_COLUMNS: readonly ["bot_channel_id"];
|
|
218
|
+
export interface ListBotSourcesParams extends ListParams<(typeof BOT_SOURCE_FILTER_COLUMNS)[number]> {
|
|
219
|
+
readonly channelId?: Id;
|
|
220
|
+
}
|
|
221
|
+
export type BotResponderRunStatus = "pending" | "running" | "done" | "failed" | "skipped";
|
|
222
|
+
export interface BotResponderRun {
|
|
223
|
+
readonly id: Id;
|
|
224
|
+
readonly created_at: Timestamp;
|
|
225
|
+
readonly updated_at: Timestamp;
|
|
226
|
+
readonly bot_channel_id: Id;
|
|
227
|
+
readonly status: BotResponderRunStatus;
|
|
228
|
+
readonly trigger: "schedule" | "manual";
|
|
229
|
+
readonly scheduled_at: Timestamp;
|
|
230
|
+
readonly started_at: Timestamp | null;
|
|
231
|
+
readonly finished_at: Timestamp | null;
|
|
232
|
+
readonly replied: number;
|
|
233
|
+
readonly escalated: number;
|
|
234
|
+
readonly error: string | null;
|
|
235
|
+
}
|
|
236
|
+
export declare const BOT_RUN_FILTER_COLUMNS: readonly ["bot_channel_id", "status", "trigger"];
|
|
237
|
+
export interface ListBotResponderRunsParams extends ListParams<(typeof BOT_RUN_FILTER_COLUMNS)[number]> {
|
|
238
|
+
readonly channelId?: Id;
|
|
239
|
+
}
|
|
240
|
+
/** One line of the owner's conversation with the responder; `meta` says what a reply did. */
|
|
241
|
+
export interface BotOwnerMessage {
|
|
242
|
+
readonly id: Id;
|
|
243
|
+
readonly created_at: Timestamp;
|
|
244
|
+
readonly updated_at: Timestamp;
|
|
245
|
+
readonly bot_channel_id: Id;
|
|
246
|
+
readonly role: "user" | "assistant";
|
|
247
|
+
readonly text: string;
|
|
248
|
+
readonly meta: {
|
|
249
|
+
readonly facts?: readonly Id[];
|
|
250
|
+
readonly removed?: readonly Id[];
|
|
251
|
+
readonly sources?: readonly Id[];
|
|
252
|
+
readonly retrying?: boolean;
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
export interface BotOwnerChat {
|
|
256
|
+
readonly messages: BotOwnerMessage[];
|
|
257
|
+
/** When the current session (no pause over two hours) started; null when there is none. */
|
|
258
|
+
readonly session_started_at: Timestamp | null;
|
|
259
|
+
/** Contacts the responder could not answer. */
|
|
260
|
+
readonly waiting: BotContact[];
|
|
261
|
+
}
|
|
262
|
+
export interface BotOwnerChatTurn {
|
|
263
|
+
readonly reply: BotOwnerMessage;
|
|
264
|
+
readonly facts: BotFact[];
|
|
265
|
+
readonly removed: Id[];
|
|
266
|
+
readonly sources: BotSource[];
|
|
267
|
+
/** Facts were saved while contacts were waiting: they are being answered in the background. */
|
|
268
|
+
readonly retrying: boolean;
|
|
269
|
+
}
|
|
270
|
+
export type BotReplyOutcome = "replied" | "escalated" | "skipped";
|
|
271
|
+
export interface BotReplyResult {
|
|
272
|
+
readonly result: BotReplyOutcome;
|
|
273
|
+
readonly contact: BotContact;
|
|
274
|
+
}
|
|
275
|
+
export interface BotTeachResult {
|
|
276
|
+
readonly learned: BotFact[];
|
|
277
|
+
readonly contact: BotContact;
|
|
278
|
+
}
|
|
279
|
+
/** `/bot_channels` - the connected bots. */
|
|
280
|
+
export declare class BotChannelsNamespace extends Resource {
|
|
281
|
+
/** `GET /bot_channels` - your channels, oldest first. */
|
|
282
|
+
list(params?: ListBotChannelsParams, options?: RequestOptions): Promise<Paginated<BotChannel>>;
|
|
283
|
+
/** `GET /bot_channels/:id`. 404 when it is not yours. */
|
|
284
|
+
get(id: Id, options?: RequestOptions): Promise<BotChannelDetail>;
|
|
285
|
+
/**
|
|
286
|
+
* `POST /bot_channels` - connect a bot. The server checks the token with the
|
|
287
|
+
* platform and registers the webhook before answering `201`.
|
|
288
|
+
*
|
|
289
|
+
* @throws {OmsApiError} 400 when the platform refuses the token, the name
|
|
290
|
+
* repeats, or the account is at its channel limit.
|
|
291
|
+
*/
|
|
292
|
+
create(input: CreateBotChannelInput, options?: RequestOptions): Promise<BotChannelDetail>;
|
|
293
|
+
/** `PATCH /bot_channels/:id`. A new `token` reconnects; a blank one is ignored. */
|
|
294
|
+
update(id: Id, input: UpdateBotChannelInput, options?: RequestOptions): Promise<BotChannelDetail>;
|
|
295
|
+
/** `DELETE /bot_channels/:id` - unregisters the webhook, drops contacts and messages. `204`. */
|
|
296
|
+
delete(id: Id, options?: RequestOptions): Promise<void>;
|
|
297
|
+
/** `POST /bot_channels/:id/test` - what the platform says about the bot and the webhook. */
|
|
298
|
+
test(id: Id, options?: RequestOptions): Promise<BotChannelStatus>;
|
|
299
|
+
}
|
|
300
|
+
/** `/bot_contacts` - who talked to your channels. Read, tag, mark read. */
|
|
301
|
+
export declare class BotContactsNamespace extends Resource {
|
|
302
|
+
/** `GET /bot_contacts` - most recently active first. */
|
|
303
|
+
list(params?: ListBotContactsParams, options?: RequestOptions): Promise<Paginated<BotContact>>;
|
|
304
|
+
get(id: Id, options?: RequestOptions): Promise<BotContact>;
|
|
305
|
+
/** `PATCH /bot_contacts/:id` - the name you give them and the tags. */
|
|
306
|
+
update(id: Id, input: UpdateBotContactInput, options?: RequestOptions): Promise<BotContact>;
|
|
307
|
+
/** `POST /bot_contacts/:id/read` - the unread counter to zero. */
|
|
308
|
+
markRead(id: Id, options?: RequestOptions): Promise<BotContact>;
|
|
309
|
+
/**
|
|
310
|
+
* `POST /bot_contacts/:id/bot_reply` - the responder handles this conversation now.
|
|
311
|
+
*
|
|
312
|
+
* @throws {OmsApiError} 400 when the channel's plugin is not the responder or it was never saved; 502 when the model or the platform failed.
|
|
313
|
+
*/
|
|
314
|
+
botReply(id: Id, options?: RequestOptions): Promise<BotReplyResult>;
|
|
315
|
+
/**
|
|
316
|
+
* `POST /bot_contacts/:id/teach` - give the responder what it was missing: the general
|
|
317
|
+
* part is kept as facts, the contact gets an answer, the others waiting are retried.
|
|
318
|
+
*/
|
|
319
|
+
teach(id: Id, hint: string, options?: RequestOptions): Promise<BotTeachResult>;
|
|
320
|
+
/** `DELETE /bot_contacts/:id` - the contact and its messages. `204`. */
|
|
321
|
+
delete(id: Id, options?: RequestOptions): Promise<void>;
|
|
322
|
+
}
|
|
323
|
+
/** `/bot_messages` - the conversations, and sending. */
|
|
324
|
+
export declare class BotMessagesNamespace extends Resource {
|
|
325
|
+
/** `GET /bot_messages` - newest first; pass `order: "sent_at:asc"` for a thread top-down. */
|
|
326
|
+
list(params?: ListBotMessagesParams, options?: RequestOptions): Promise<Paginated<BotMessage>>;
|
|
327
|
+
get(id: Id, options?: RequestOptions): Promise<BotMessage>;
|
|
328
|
+
/**
|
|
329
|
+
* `POST /bot_messages` - send. The server talks to the platform and records
|
|
330
|
+
* the message with source `api` (a token) or `human` (a session).
|
|
331
|
+
*
|
|
332
|
+
* @throws {OmsApiError} 422 when the contact blocked the bot; 429 at the daily
|
|
333
|
+
* limit; 502 when the platform refused (the row is kept with `error`).
|
|
334
|
+
*/
|
|
335
|
+
send(input: SendBotMessageInput, options?: RequestOptions): Promise<BotMessage>;
|
|
336
|
+
/** `DELETE /bot_messages/:id` - one row out of the thread. `204`. */
|
|
337
|
+
delete(id: Id, options?: RequestOptions): Promise<void>;
|
|
338
|
+
}
|
|
339
|
+
/** `/bot_channels/:id/responder` - the responder plugin of a channel. */
|
|
340
|
+
export declare class BotRespondersNamespace extends Resource {
|
|
341
|
+
/** @throws {OmsApiError} 400 when the channel's plugin is not the responder. */
|
|
342
|
+
get(channelId: Id, options?: RequestOptions): Promise<BotResponder>;
|
|
343
|
+
/** `PATCH /bot_channels/:id/responder` - creates it on first save. */
|
|
344
|
+
update(channelId: Id, input: UpdateBotResponderInput, options?: RequestOptions): Promise<BotResponder>;
|
|
345
|
+
/**
|
|
346
|
+
* `POST /bot_channels/:id/responder/run` - answer the pending conversations now, outside the schedule.
|
|
347
|
+
*
|
|
348
|
+
* @throws {OmsApiError} 400 when a run is already open or the responder was never saved.
|
|
349
|
+
*/
|
|
350
|
+
run(channelId: Id, options?: RequestOptions): Promise<BotResponderRun>;
|
|
351
|
+
}
|
|
352
|
+
/** `/bot_channels/:id/owner_chat` - the owner talking to the responder: teach, ask, correct, delete, point to sources. */
|
|
353
|
+
export declare class BotOwnerChatNamespace extends Resource {
|
|
354
|
+
get(channelId: Id, options?: RequestOptions): Promise<BotOwnerChat>;
|
|
355
|
+
/**
|
|
356
|
+
* `POST /bot_channels/:id/owner_chat` - one turn. The model's decisions are applied before the answer comes back.
|
|
357
|
+
*
|
|
358
|
+
* @throws {OmsApiError} 400 when the channel's plugin is not the responder or it was never saved; 502 when the model failed.
|
|
359
|
+
*/
|
|
360
|
+
send(channelId: Id, message: string, options?: RequestOptions): Promise<BotOwnerChatTurn>;
|
|
361
|
+
}
|
|
362
|
+
/** `/bot_facts` - what the responder knows, with optional validity dates. */
|
|
363
|
+
export declare class BotFactsNamespace extends Resource {
|
|
364
|
+
list(params?: ListBotFactsParams, options?: RequestOptions): Promise<Paginated<BotFact>>;
|
|
365
|
+
get(id: Id, options?: RequestOptions): Promise<BotFact>;
|
|
366
|
+
/** @throws {OmsApiError} 400 when the channel's plugin is not the responder. */
|
|
367
|
+
create(input: CreateBotFactInput, options?: RequestOptions): Promise<BotFact>;
|
|
368
|
+
update(id: Id, input: UpdateBotFactInput, options?: RequestOptions): Promise<BotFact>;
|
|
369
|
+
delete(id: Id, options?: RequestOptions): Promise<void>;
|
|
370
|
+
}
|
|
371
|
+
/** `/bot_sources` - pages the responder may read when a question calls for it. */
|
|
372
|
+
export declare class BotSourcesNamespace extends Resource {
|
|
373
|
+
list(params?: ListBotSourcesParams, options?: RequestOptions): Promise<Paginated<BotSource>>;
|
|
374
|
+
get(id: Id, options?: RequestOptions): Promise<BotSource>;
|
|
375
|
+
create(input: CreateBotSourceInput, options?: RequestOptions): Promise<BotSource>;
|
|
376
|
+
update(id: Id, input: UpdateBotSourceInput, options?: RequestOptions): Promise<BotSource>;
|
|
377
|
+
delete(id: Id, options?: RequestOptions): Promise<void>;
|
|
378
|
+
}
|
|
379
|
+
/** `/bot_responder_runs` - the responder's passes over the conversations, newest first. */
|
|
380
|
+
export declare class BotResponderRunsNamespace extends Resource {
|
|
381
|
+
list(params?: ListBotResponderRunsParams, options?: RequestOptions): Promise<Paginated<BotResponderRun>>;
|
|
382
|
+
get(id: Id, options?: RequestOptions): Promise<BotResponderRun>;
|
|
383
|
+
}
|
|
384
|
+
export declare class BotsNamespace extends Resource {
|
|
385
|
+
readonly channels: BotChannelsNamespace;
|
|
386
|
+
readonly contacts: BotContactsNamespace;
|
|
387
|
+
readonly messages: BotMessagesNamespace;
|
|
388
|
+
readonly responders: BotRespondersNamespace;
|
|
389
|
+
readonly ownerChat: BotOwnerChatNamespace;
|
|
390
|
+
readonly facts: BotFactsNamespace;
|
|
391
|
+
readonly sources: BotSourcesNamespace;
|
|
392
|
+
readonly runs: BotResponderRunsNamespace;
|
|
393
|
+
constructor(http: ApiClient);
|
|
394
|
+
}
|
|
@@ -10,7 +10,9 @@ export declare const NEWS_FEED_MAX_RETENTION_DAYS = 3650;
|
|
|
10
10
|
/**
|
|
11
11
|
* A feed: a named set of {@link NewsSource}s and the {@link NewsItem}s they
|
|
12
12
|
* produce. Several per account, unique by name; the oldest is the default
|
|
13
|
-
* one a source lands in when it names no feed.
|
|
13
|
+
* one a source lands in when it names no feed. A feed may INCLUDE other
|
|
14
|
+
* feeds of yours (one level): listing its items also returns theirs, so
|
|
15
|
+
* sources can be grouped by kind ("Newspapers", "TV news") and reused.
|
|
14
16
|
*/
|
|
15
17
|
export interface NewsFeed {
|
|
16
18
|
readonly id: Id;
|
|
@@ -24,11 +26,14 @@ export interface NewsFeed {
|
|
|
24
26
|
readonly retention_days: number;
|
|
25
27
|
/** A disabled feed's sources are not polled. */
|
|
26
28
|
readonly enabled: boolean;
|
|
29
|
+
/** Feeds of yours whose items this feed also lists (one level, no chaining). */
|
|
30
|
+
readonly included_feed_ids: Id[];
|
|
27
31
|
}
|
|
28
|
-
/** `GET /news_feeds/:id` adds two live counters. */
|
|
32
|
+
/** `GET /news_feeds/:id` adds two live counters (this feed's own sources and items) and who includes it. */
|
|
29
33
|
export interface NewsFeedDetail extends NewsFeed {
|
|
30
34
|
readonly sources_count: number;
|
|
31
35
|
readonly items_count: number;
|
|
36
|
+
readonly included_by_feed_ids: Id[];
|
|
32
37
|
}
|
|
33
38
|
/** Filter columns of `GET /news_feeds`, on top of {@link BASE_FILTER_COLUMNS}. */
|
|
34
39
|
export declare const NEWS_FEED_FILTER_COLUMNS: readonly ["name", "enabled"];
|
|
@@ -39,6 +44,8 @@ export interface CreateNewsFeedInput {
|
|
|
39
44
|
readonly description?: string | null;
|
|
40
45
|
readonly retentionDays?: number;
|
|
41
46
|
readonly enabled?: boolean;
|
|
47
|
+
/** REPLACES the list. Your own feeds only, the feed itself is dropped; anything else is a `400`. */
|
|
48
|
+
readonly includedFeedIds?: readonly Id[];
|
|
42
49
|
}
|
|
43
50
|
export type UpdateNewsFeedInput = Partial<CreateNewsFeedInput>;
|
|
44
51
|
/** `/news_feeds` - your feeds. Needs `news:read` to read and `news:write` to change. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** The `news` namespace and everything under it. */
|
|
2
2
|
import { type ApiClient, Resource } from "../../../http";
|
|
3
|
+
import type { RequestOptions } from "../../../types";
|
|
3
4
|
import { NewsFeedsNamespace } from "./feeds";
|
|
4
5
|
import { NewsItemsNamespace } from "./items";
|
|
5
6
|
import { NewsScriptsNamespace } from "./scripts";
|
|
@@ -8,6 +9,21 @@ export * from "./feeds";
|
|
|
8
9
|
export * from "./items";
|
|
9
10
|
export * from "./scripts";
|
|
10
11
|
export * from "./sources";
|
|
12
|
+
/** One feed a site declares or answers on a common path, already read and measured. */
|
|
13
|
+
export interface DiscoveredFeed {
|
|
14
|
+
readonly url: string;
|
|
15
|
+
readonly kind: "rss" | "atom";
|
|
16
|
+
readonly title: string;
|
|
17
|
+
readonly items: number;
|
|
18
|
+
/** Entries carrying a date. */
|
|
19
|
+
readonly dated: number;
|
|
20
|
+
}
|
|
21
|
+
export interface NewsDiscovery {
|
|
22
|
+
readonly url: string;
|
|
23
|
+
readonly host: string;
|
|
24
|
+
readonly title: string;
|
|
25
|
+
readonly feeds: DiscoveredFeed[];
|
|
26
|
+
}
|
|
11
27
|
/**
|
|
12
28
|
* The `news` namespace, reachable as `oms.content.news`: the ingestion side
|
|
13
29
|
* of following the web.
|
|
@@ -33,4 +49,11 @@ export declare class NewsNamespace extends Resource {
|
|
|
33
49
|
/** What the sources produced. Read plus delete. */
|
|
34
50
|
readonly items: NewsItemsNamespace;
|
|
35
51
|
constructor(http: ApiClient);
|
|
52
|
+
/**
|
|
53
|
+
* `GET /news/discover?url=` - the RSS/Atom feeds of a site: the ones its page declares
|
|
54
|
+
* and the common paths that answer, each fetched and measured. Cached for hours server-side.
|
|
55
|
+
*
|
|
56
|
+
* @throws {OmsApiError} 422 when the site cannot be read (the message says why).
|
|
57
|
+
*/
|
|
58
|
+
discover(url: string, options?: RequestOptions): Promise<NewsDiscovery>;
|
|
36
59
|
}
|
|
@@ -38,8 +38,20 @@ export interface NewsSource {
|
|
|
38
38
|
readonly config: Record<string, Json>;
|
|
39
39
|
/** The {@link NewsFeed} it belongs to. */
|
|
40
40
|
readonly news_feed_id: Id;
|
|
41
|
-
/** Which {@link NewsScript} fetches this source. */
|
|
42
|
-
readonly news_script_id: Id;
|
|
41
|
+
/** Which {@link NewsScript} fetches this source, or `null` when a job does. */
|
|
42
|
+
readonly news_script_id: Id | null;
|
|
43
|
+
/**
|
|
44
|
+
* The cron job (`oms.cron.jobs`, with `output` items) that fetches this
|
|
45
|
+
* source instead of a script, and the schedule of that job the source owns:
|
|
46
|
+
* its `cron` comes from `poll_interval_minutes` and its `params` are the
|
|
47
|
+
* source's `config`. `null` for a script source.
|
|
48
|
+
*/
|
|
49
|
+
readonly cron_job_id: Id | null;
|
|
50
|
+
readonly cron_schedule_id: Id | null;
|
|
51
|
+
/** The schedule's cron expression, for a job source. */
|
|
52
|
+
readonly cron: string | null;
|
|
53
|
+
/** Where the job runs, for a job source: `sandbox` or `full`. */
|
|
54
|
+
readonly runtime: "sandbox" | "full" | null;
|
|
43
55
|
/** Minutes between polls. Validated `in: 5..1440`. */
|
|
44
56
|
readonly poll_interval_minutes: number;
|
|
45
57
|
/**
|
|
@@ -67,7 +79,7 @@ export interface NewsSource {
|
|
|
67
79
|
readonly consecutive_failures: number;
|
|
68
80
|
}
|
|
69
81
|
/** Filter columns of `GET /news_sources`, on top of {@link BASE_FILTER_COLUMNS}. */
|
|
70
|
-
export declare const NEWS_SOURCE_FILTER_COLUMNS: readonly ["name", "health", "enabled", "news_feed_id", "news_script_id"];
|
|
82
|
+
export declare const NEWS_SOURCE_FILTER_COLUMNS: readonly ["name", "health", "enabled", "news_feed_id", "news_script_id", "cron_job_id"];
|
|
71
83
|
/** Filters for {@link NewsSourcesNamespace.list}. */
|
|
72
84
|
export interface ListNewsSourcesParams extends ListParams<(typeof NEWS_SOURCE_FILTER_COLUMNS)[number]> {
|
|
73
85
|
/** Only healthy / only broken sources. Sent as `exact_search[health]`. */
|
|
@@ -78,6 +90,8 @@ export interface ListNewsSourcesParams extends ListParams<(typeof NEWS_SOURCE_FI
|
|
|
78
90
|
readonly feedId?: Id;
|
|
79
91
|
/** Every source driven by one script. */
|
|
80
92
|
readonly scriptId?: Id;
|
|
93
|
+
/** Every source driven by one job. */
|
|
94
|
+
readonly jobId?: Id;
|
|
81
95
|
}
|
|
82
96
|
/** Arguments for {@link NewsSourcesNamespace.create}. */
|
|
83
97
|
export interface CreateNewsSourceInput {
|
|
@@ -89,9 +103,17 @@ export interface CreateNewsSourceInput {
|
|
|
89
103
|
* The script that fetches it. Must be a built-in or one of yours;
|
|
90
104
|
* `script_visible_to_owner` rejects anything else with
|
|
91
105
|
* `400 "News script is not accessible"` rather than a 404, so this also
|
|
92
|
-
* tells you the id exists. Do not use it as an existence oracle.
|
|
106
|
+
* tells you the id exists. Do not use it as an existence oracle. Give
|
|
107
|
+
* either this or `jobId`.
|
|
93
108
|
*/
|
|
94
|
-
readonly scriptId
|
|
109
|
+
readonly scriptId?: Id;
|
|
110
|
+
/**
|
|
111
|
+
* A cron job of yours with `output: { kind: "items" }` that fetches it
|
|
112
|
+
* instead of a script. The source gets a schedule of that job: the cron
|
|
113
|
+
* from `pollIntervalMinutes`, the `config` as the run params. `400` when
|
|
114
|
+
* the job has no items output.
|
|
115
|
+
*/
|
|
116
|
+
readonly jobId?: Id;
|
|
95
117
|
/** Whatever that script reads. Free-form; the API validates nothing in it. */
|
|
96
118
|
readonly config?: Record<string, Json>;
|
|
97
119
|
/** 5-1440. Defaults to 15 server-side. */
|
|
@@ -104,11 +126,36 @@ export interface CreateNewsSourceInput {
|
|
|
104
126
|
*
|
|
105
127
|
* One key wider than the create form: `cursor` is updatable and not creatable.
|
|
106
128
|
*/
|
|
129
|
+
/** Arguments for {@link NewsSourcesNamespace.test}: a script, or a sandbox job (its config goes under the given one). */
|
|
130
|
+
export interface TestNewsSourceInput {
|
|
131
|
+
readonly scriptId?: Id;
|
|
132
|
+
readonly jobId?: Id;
|
|
133
|
+
readonly config?: Record<string, Json>;
|
|
134
|
+
}
|
|
135
|
+
export interface NewsSourceTestItem {
|
|
136
|
+
readonly external_id: string;
|
|
137
|
+
readonly title: string;
|
|
138
|
+
readonly url: string | null;
|
|
139
|
+
readonly published_at: Timestamp | null;
|
|
140
|
+
readonly content: string | null;
|
|
141
|
+
}
|
|
142
|
+
/** What a dry run produced. `ok: false` carries the script's error. */
|
|
143
|
+
export interface NewsSourceTest {
|
|
144
|
+
readonly ok: boolean;
|
|
145
|
+
readonly error?: string;
|
|
146
|
+
readonly items: NewsSourceTestItem[];
|
|
147
|
+
readonly count: number;
|
|
148
|
+
/** Items published in the last 30 days. */
|
|
149
|
+
readonly dated: number;
|
|
150
|
+
readonly logs: string[];
|
|
151
|
+
}
|
|
107
152
|
export interface UpdateNewsSourceInput {
|
|
108
153
|
readonly name?: string;
|
|
109
154
|
/** Moves the source (and nothing else: its items stay where they were written) to another of your feeds. */
|
|
110
155
|
readonly newsFeedId?: Id;
|
|
156
|
+
/** Setting a script drops the job (and its schedule); setting a job drops the script. */
|
|
111
157
|
readonly scriptId?: Id;
|
|
158
|
+
readonly jobId?: Id;
|
|
112
159
|
/**
|
|
113
160
|
* REPLACES the whole object; there is no merge. `assign_attributes` writes
|
|
114
161
|
* the JSON column wholesale, so sending `{ url: "..." }` to a source that
|
|
@@ -235,5 +282,14 @@ export declare class NewsSourcesNamespace extends Resource {
|
|
|
235
282
|
* @throws {OmsApiError} 404 `"Resource not found"` when the source is not
|
|
236
283
|
* yours.
|
|
237
284
|
*/
|
|
285
|
+
/**
|
|
286
|
+
* `POST /news_sources/test` - run a script with a config once, with no cursor
|
|
287
|
+
* and without creating anything, and get back the items it would produce.
|
|
288
|
+
* The dry run before creating or repairing a source.
|
|
289
|
+
*
|
|
290
|
+
* @throws {OmsApiError} 400 when the script is not a built-in or one of
|
|
291
|
+
* yours; 502 when the runner is down.
|
|
292
|
+
*/
|
|
293
|
+
test(input: TestNewsSourceInput, options?: RequestOptions): Promise<NewsSourceTest>;
|
|
238
294
|
run(id: Id, options?: RequestOptions): Promise<NewsSourceRunAccepted>;
|
|
239
295
|
}
|