@oxygen-agent/cli 1.1011.687 → 1.1011.800
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 +1 -1
- package/dist/column-run-notices.js +2 -0
- package/dist/help.d.ts +2 -0
- package/dist/help.js +5 -0
- package/dist/index.js +245 -158
- package/dist/workflow-run-list-flags.d.ts +3 -0
- package/dist/workflow-run-list-flags.js +21 -0
- package/node_modules/@oxygen/shared/dist/capability-discovery.js +65 -14
- package/node_modules/@oxygen/shared/dist/contracts/crm-enrichment-read.js +1 -1
- package/node_modules/@oxygen/shared/dist/contracts/crm-support.d.ts +1 -0
- package/node_modules/@oxygen/shared/dist/contracts/crm-support.js +1 -0
- package/node_modules/@oxygen/shared/dist/contracts/customer-operations.js +8 -6
- package/node_modules/@oxygen/shared/dist/contracts/operations.js +2 -1
- package/node_modules/@oxygen/shared/dist/contracts/schema.d.ts +8 -0
- package/node_modules/@oxygen/shared/dist/contracts/schema.js +6 -0
- package/node_modules/@oxygen/shared/dist/contracts/sequence-analytics-read.d.ts +38 -0
- package/node_modules/@oxygen/shared/dist/contracts/sequence-analytics-read.js +22 -0
- package/node_modules/@oxygen/shared/dist/contracts/table-feed-update.d.ts +222 -0
- package/node_modules/@oxygen/shared/dist/contracts/table-feed-update.js +55 -0
- package/node_modules/@oxygen/shared/dist/contracts/table-list.d.ts +31 -0
- package/node_modules/@oxygen/shared/dist/contracts/table-list.js +22 -0
- package/node_modules/@oxygen/shared/dist/contracts/table-operations.d.ts +58 -0
- package/node_modules/@oxygen/shared/dist/contracts/table-operations.js +30 -0
- package/node_modules/@oxygen/shared/dist/contracts/workflow-run-list.d.ts +79 -0
- package/node_modules/@oxygen/shared/dist/contracts/workflow-run-list.js +38 -0
- package/node_modules/@oxygen/shared/dist/copilot-journeys.d.ts +2 -2
- package/node_modules/@oxygen/shared/dist/copilot-journeys.generated.d.ts +2 -2
- package/node_modules/@oxygen/shared/dist/copilot-journeys.generated.js +2 -2
- package/node_modules/@oxygen/shared/dist/copilot-playbooks.generated.d.ts +3 -3
- package/node_modules/@oxygen/shared/dist/copilot-playbooks.generated.js +3 -3
- package/node_modules/@oxygen/shared/dist/hosted-ai.js +24 -0
- package/node_modules/@oxygen/shared/dist/recipes.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/recipes.js +4 -9
- package/node_modules/@oxygen/shared/dist/version.generated.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/version.generated.js +1 -1
- package/node_modules/@oxygen/workflows/dist/graph/expression.d.ts +1 -0
- package/node_modules/@oxygen/workflows/dist/graph/expression.js +15 -0
- package/node_modules/@oxygen/workflows/dist/graph/lint.js +8 -2
- package/package.json +1 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { WORKFLOW_RUN_LIST_CONTRACT } from "@oxygen/shared/contracts/workflow-run-list";
|
|
2
|
+
import { readContractFlags } from "./contract-flags.js";
|
|
3
|
+
import { readPositiveInt } from "./cli-values.js";
|
|
4
|
+
import { readOption } from "./util.js";
|
|
5
|
+
export const WORKFLOW_RUN_LIST_FLAG_OVERLAY = {
|
|
6
|
+
workflow: { valueName: "<workflow>", parse: readOption },
|
|
7
|
+
workflow_id: { valueName: "<workflow_id>", help: "Workflow id or slug; legacy CLI --workflow takes precedence.", parse: readOption },
|
|
8
|
+
status: { valueName: "<status>", parse: readOption },
|
|
9
|
+
mode: { valueName: "<mode>", parse: readOption },
|
|
10
|
+
cursor: { valueName: "<cursor>", parse: readOption },
|
|
11
|
+
// Preserve the shipped CLI parser: native HTTP owns the upper-500 refusal.
|
|
12
|
+
limit: { valueName: "<n>", parse: readPositiveInt },
|
|
13
|
+
};
|
|
14
|
+
export function readWorkflowRunListFlags(options) {
|
|
15
|
+
const args = readContractFlags(options, WORKFLOW_RUN_LIST_CONTRACT, WORKFLOW_RUN_LIST_FLAG_OVERLAY);
|
|
16
|
+
const workflow = args.workflow ?? args.workflow_id;
|
|
17
|
+
delete args.workflow_id;
|
|
18
|
+
if (workflow !== undefined)
|
|
19
|
+
args.workflow = workflow;
|
|
20
|
+
return args;
|
|
21
|
+
}
|
|
@@ -574,26 +574,17 @@ export function inferCapabilityRoute(query) {
|
|
|
574
574
|
// Its source nouns otherwise select a one-shot post search or follower order.
|
|
575
575
|
if (isLinkedInAudienceCampaignIntent(query)) {
|
|
576
576
|
const recipes = ROUTE_BY_ID.get("recipes");
|
|
577
|
-
const slug = query.trim().toLowerCase();
|
|
578
|
-
const namedPlay = AUDIENCE_PLAY_SLUGS.includes(slug) ? slug : null;
|
|
579
577
|
if (recipes)
|
|
580
578
|
return {
|
|
581
579
|
card: {
|
|
582
580
|
...recipes,
|
|
583
|
-
execution: "
|
|
581
|
+
execution: "Read the inbound-led-outbound Recipe and pick its source (your posts, a competitor's or creator's posts, a topic, your profile viewers, or your followers and connections), resolve current company/ICP context, then read the oxygen-signals file references/audience-campaigns.md. Preserve the exact source, attribution, qualification rule/version and object IDs. Prepare a bounded native audience campaign for email, LinkedIn DM/connection requests or WhatsApp. Keep capture, standing qualification, router and Sequence disabled until their own approval and credit scope; the shared guide owns execution.",
|
|
584
582
|
skills: ["oxygen-recipes", "oxygen-signals"],
|
|
585
583
|
},
|
|
586
584
|
recommendedTools: ["oxygen_recipes_list", "oxygen_recipes_get", "oxygen_context_resolve"],
|
|
587
585
|
recommendedCommands: ["recipes list", "recipes show", "context resolve"],
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
exactCommand: `oxygen recipes show ${namedPlay} --json`,
|
|
591
|
-
exactMcpCall: { tool: "oxygen_recipes_get", arguments: { slug: namedPlay } },
|
|
592
|
-
}
|
|
593
|
-
: {
|
|
594
|
-
exactCommand: 'oxygen recipes list "linkedin audience" --view summary --json',
|
|
595
|
-
exactMcpCall: { tool: "oxygen_recipes_list", arguments: { query: "linkedin audience", view: "summary" } },
|
|
596
|
-
}),
|
|
586
|
+
exactCommand: `oxygen recipes show ${AUDIENCE_PLAY_SLUG} --json`,
|
|
587
|
+
exactMcpCall: { tool: "oxygen_recipes_get", arguments: { slug: AUDIENCE_PLAY_SLUG } },
|
|
597
588
|
};
|
|
598
589
|
}
|
|
599
590
|
const explicit = explicitCapabilityIntent(normalized);
|
|
@@ -817,8 +808,11 @@ export function serializeCapabilityRoute(route, surfaceOrOptions = "cli", option
|
|
|
817
808
|
function normalizeIntent(query) {
|
|
818
809
|
return query.toLowerCase().replace(/[_-]+/g, " ").replace(/\s+/g, " ").trim();
|
|
819
810
|
}
|
|
820
|
-
/** The
|
|
811
|
+
/** The one LinkedIn audience-campaign Recipe since the 2026-10-04 consolidation. */
|
|
812
|
+
const AUDIENCE_PLAY_SLUG = "inbound-led-outbound";
|
|
813
|
+
/** The six audience Recipes it absorbed or replaced; a bare old slug still names the play. */
|
|
821
814
|
const AUDIENCE_PLAY_SLUGS = [
|
|
815
|
+
AUDIENCE_PLAY_SLUG,
|
|
822
816
|
"own-post-engagers",
|
|
823
817
|
"competitor-post-engagers",
|
|
824
818
|
"creator-post-engagers",
|
|
@@ -952,8 +946,42 @@ const UGC_ROUTE_VIEW = {
|
|
|
952
946
|
posture: "mixed",
|
|
953
947
|
skills: ["oxygen-ugc", "oxygen-publishing"],
|
|
954
948
|
};
|
|
949
|
+
/** Saved CRM preset configuration is a Records read, not an enrichment run. */
|
|
950
|
+
function isCrmEnrichmentConfigurationRead(query) {
|
|
951
|
+
if (!/\bcrm\b/.test(query) || !/\benrich\w*\b/.test(query))
|
|
952
|
+
return false;
|
|
953
|
+
// Remove only local negated execution restrictions. A later positive verb
|
|
954
|
+
// ("read, do not change this, then enable...") still rejects this read view.
|
|
955
|
+
const intent = query.replace(/\bnot a provider run\b/g, "")
|
|
956
|
+
.replace(/\b(?:do not|don't|without)\s+(?:any\s+)?(?:chang(?:e|ing)|runn?ing|run|enabl(?:e|ing)|disabl(?:e|ing)|configur(?:e|ing)|send(?:ing)?|sync(?:ing)?)\b/g, "");
|
|
957
|
+
if (/\b(tables?|columns?|workflows?|agents?|functions?|callables?|providers?|hubspot|sync|deals?|custom|fields?|values?|history|failed|items?)\b/.test(intent))
|
|
958
|
+
return false;
|
|
959
|
+
if (/\b(enable|disable|set|configure|change|run|running|backfill|send|create|start|execute|apply)\b/.test(intent))
|
|
960
|
+
return false;
|
|
961
|
+
return /\b(configur(?:ation|ed)|settings?|presets?|auto(?:matic)?|armed|enabled|backlog)\b/.test(intent)
|
|
962
|
+
&& /\b(read|inspect|list|show|view|what|which|how many|current|existing|already)\b/.test(intent);
|
|
963
|
+
}
|
|
964
|
+
function crmEnrichmentReadRecommendation(query) {
|
|
965
|
+
const omitCounts = /\b(?:skip|omit|leave)\b.{0,45}\bcounts?\b|\bwithout\b.{0,45}\b(?:counts?|scanning historical records)\b/.test(query);
|
|
966
|
+
return {
|
|
967
|
+
tools: ["oxygen_crm_enrichment"], commands: ["crm enrichment list"],
|
|
968
|
+
exactCommand: `oxygen crm enrichment list${omitCounts ? " --no-backfill" : ""} --projection summary --json`,
|
|
969
|
+
exactMcpCall: { tool: "oxygen_crm_enrichment", arguments: { action: "list", ...(omitCounts ? { backfill: false } : {}), projection: "summary" } },
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
const CRM_ENRICHMENT_READ_VIEW = {
|
|
973
|
+
owns: "Saved automatic-enrichment presets and batch caps for native CRM companies/people, backed by Tables auto-run.",
|
|
974
|
+
notFor: "Running enrichment, provider catalog/sourcing, linked working Tables, external CRM sync, or changing the standing grant.",
|
|
975
|
+
execution: "Read the saved configuration with action=list, free through oxygen_capabilities_call: this tool also writes, so its paid/write annotations and built-in approval policy remain. Omit object and use backfill=false to skip historical counts; object reads ignore it. summary is compact; preset_count counts catalog entries, trigger_default is the current plan-default cap, and backfill:null means no count was produced. set/enable/disable change standing auto-run; action=backfill previews for free, while paid live batches require native approval and a ceiling.",
|
|
976
|
+
posture: "mixed",
|
|
977
|
+
};
|
|
955
978
|
/** The card a route reports: Publishing's own, or its UGC view for a creator-program ask. */
|
|
956
979
|
function routeCardFor(card, query) {
|
|
980
|
+
if (card.id === "records" && isCrmEnrichmentConfigurationRead(query))
|
|
981
|
+
return { ...card, ...CRM_ENRICHMENT_READ_VIEW };
|
|
982
|
+
const feed = card.primitive === "tables" ? tableFeedRecommendation(query) : null;
|
|
983
|
+
if (feed)
|
|
984
|
+
return { ...card, execution: feed.execution };
|
|
957
985
|
if (card.primitive === "publishing" && isUgcIntent(query))
|
|
958
986
|
return { ...card, ...UGC_ROUTE_VIEW };
|
|
959
987
|
const contactFind = card.id === "sourcing-and-provider-tools" ? oneShotContactFindingRecommendation(query) : null;
|
|
@@ -1463,7 +1491,7 @@ function tableMaintenanceRecommendation(query) {
|
|
|
1463
1491
|
if (table && /\bfeeds?\b/.test(query)) {
|
|
1464
1492
|
return /\b(bind|attach|create|new)\b/.test(query)
|
|
1465
1493
|
? result(["oxygen_feeds_bind", "oxygen_feeds_list"], ["feeds bind", "feeds list"], "Bind the native Table feed: a declared-schema push source or scheduled provider pull. Inspect source, cadence and standing credit scope first; a pull feed is not an inbound webhook endpoint.")
|
|
1466
|
-
: result(["oxygen_feeds_list", "oxygen_feeds_get"], ["feeds list", "feeds get"], "Inspect the
|
|
1494
|
+
: result(["oxygen_feeds_list", "oxygen_feeds_get", "oxygen_feeds_update"], ["feeds list", "feeds get", "feeds update"], "Inspect the Table feed with feeds_get(include_route=true), then update it in place via oxygen_feeds_update (Signals pack/core write gateway) or feeds update. Preserve the full frozen request; source replacement resets its cursor. Scheduled replacements require one executable lane; fallbacks require no cadence. Native changed cadence or expanded paid source/cap authority can require renewed standing approval; configuration is free.");
|
|
1467
1495
|
}
|
|
1468
1496
|
const file = /\b(csv|jsonl?|xlsx|excel|spreadsheet|staged|uploaded|file)\b/.test(query)
|
|
1469
1497
|
|| /\b(?:pending|stuck|abandoned) imports?\b|\bimports?\b.{0,30}\b(pending|stuck|recover\w*)\b/.test(query);
|
|
@@ -1537,9 +1565,25 @@ function oneShotContactFindingRecommendation(query) {
|
|
|
1537
1565
|
execution: "Hydrate the selected native one-shot lookup schema. mode=dry_run previews its waterfall; live requires the user's approved exact scope and positive max_credits. readOnlyHint=false and openWorldHint=true still apply to previews. External MCP uses oxygen_capabilities_call for an unlisted lookup; built-in agents call the native capability under their existing policy. Free catalog metadata uses the read gateway. Sending and bulk Table enrichment have separate owners.",
|
|
1538
1566
|
};
|
|
1539
1567
|
}
|
|
1568
|
+
/** Native row-supply feeds belong to Tables; Signals is their registered MCP pack. */
|
|
1569
|
+
function tableFeedRecommendation(rawQuery) {
|
|
1570
|
+
// A pasted URL (e.g. linkedin.com/feed/update/...) names a resource, not a Table feed.
|
|
1571
|
+
const query = rawQuery.replace(/\bhttps?:\/\/\S+/g, " ");
|
|
1572
|
+
if (/\b(workflows?|agents?|rss|knowledge|mailbox\w*|crm|attachments?|webhooks?|inbound endpoints?|sequences?|publishing)\b/.test(query))
|
|
1573
|
+
return null;
|
|
1574
|
+
const explicit = /\bfeeds?\b/.test(query) && /\b(tables?|pull|cadence|refresh|saved search|source|filters?|credit|credits|caps?|update|bind)\b/.test(query);
|
|
1575
|
+
const saved = /\btables?\b/.test(query) && /\bsaved search\b/.test(query) && /\b(refill\w*|refresh\w*|scheduled|cadence)\b/.test(query);
|
|
1576
|
+
if (!explicit && !saved)
|
|
1577
|
+
return null;
|
|
1578
|
+
if (/\b(bind|attach|create|new)\b/.test(query))
|
|
1579
|
+
return { tools: ["oxygen_feeds_bind", "oxygen_feeds_list"], commands: ["feeds bind", "feeds list"], execution: "Bind the native Table row-supply feed. Inspect source, cadence and standing credit scope first; pull feeds are distinct from inbound webhook endpoints. Feed tools are executable through the core gateways or Signals pack." };
|
|
1580
|
+
return { tools: ["oxygen_feeds_list", "oxygen_feeds_get", "oxygen_feeds_update"], commands: ["feeds list", "feeds get", "feeds update"], execution: "Inspect the existing Table feed with feeds_get(include_route=true), then update it in place with oxygen_feeds_update (Signals pack or core write gateway). Preserve the complete frozen request; source replacement resets the cursor. Scheduled replacements require one executable lane; fallbacks require no cadence. Changed cadence, increased paid cap or replaced paid source can require renewed standing authorization. Configuration is free; future refreshes retain their approved cycle ceiling." };
|
|
1581
|
+
}
|
|
1540
1582
|
function explicitCapabilityIntent(query) {
|
|
1541
1583
|
if (sentLinkedInInvitationReadRecommendation(query))
|
|
1542
1584
|
return ROUTE_BY_ID.get("connected-linkedin") ?? null;
|
|
1585
|
+
if (isCrmEnrichmentConfigurationRead(query))
|
|
1586
|
+
return ROUTE_BY_ID.get("records") ?? null;
|
|
1543
1587
|
if (databaseRecommendation(query))
|
|
1544
1588
|
return ROUTE_BY_ID.get("platform-operations") ?? null;
|
|
1545
1589
|
if (oneShotContactFindingRecommendation(query))
|
|
@@ -1548,6 +1592,8 @@ function explicitCapabilityIntent(query) {
|
|
|
1548
1592
|
return ROUTE_BY_ID.get("records") ?? null;
|
|
1549
1593
|
if (storedReplyDraftReadRecommendation(query))
|
|
1550
1594
|
return ROUTE_BY_PRIMITIVE.get("messages") ?? null;
|
|
1595
|
+
if (tableFeedRecommendation(query))
|
|
1596
|
+
return ROUTE_BY_PRIMITIVE.get("tables") ?? null;
|
|
1551
1597
|
if (isConnectedAppsIntent(query) || isConnectedAppEventsIntent(query) || isConnectedAppSpendIntent(query)) {
|
|
1552
1598
|
return ROUTE_BY_ID.get("workspace-access") ?? null;
|
|
1553
1599
|
}
|
|
@@ -1850,9 +1896,14 @@ function recommendationsFor(card, query) {
|
|
|
1850
1896
|
const sent = card.id === "connected-linkedin" ? sentLinkedInInvitationReadRecommendation(query) : null;
|
|
1851
1897
|
if (sent)
|
|
1852
1898
|
return sent;
|
|
1899
|
+
if (card.id === "records" && isCrmEnrichmentConfigurationRead(query))
|
|
1900
|
+
return crmEnrichmentReadRecommendation(query);
|
|
1853
1901
|
const database = card.id === "platform-operations" ? databaseRecommendation(query) : null;
|
|
1854
1902
|
if (database)
|
|
1855
1903
|
return database;
|
|
1904
|
+
const feed = card.primitive === "tables" ? tableFeedRecommendation(query) : null;
|
|
1905
|
+
if (feed)
|
|
1906
|
+
return { tools: feed.tools, commands: feed.commands };
|
|
1856
1907
|
if (card.id === "billing-and-budgets" && /\b(credit prices|credit price catalog|customer credit)\b/.test(query)) {
|
|
1857
1908
|
return { tools: ["oxygen_customer_credit_prices"], commands: ["pricing customer-credit-prices"] };
|
|
1858
1909
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { bool, enumOf, int, obj, str } from "./schema.js";
|
|
2
2
|
/** Read selectors only; action=backfill is a separate governed operation. */
|
|
3
3
|
export const CRM_ENRICHMENT_READ_CONTRACT = obj({
|
|
4
|
-
object: str({ minLength: 1, maxLength: 120, description: "CRM object
|
|
4
|
+
object: str({ minLength: 1, maxLength: 120, description: "CRM object: companies or people." }),
|
|
5
5
|
backfill: bool({ description: "list without object: include stored historical backlog counts (default true). false skips the scans; object reads ignore it. Never runs enrichment." }),
|
|
6
6
|
projection: enumOf(["summary", "full", "value"], { description: "summary: standing configuration without long arrays. full: legacy data. value: lossless JSON of path, continued with next_cursor. Omit for legacy output." }),
|
|
7
7
|
path: str({ maxLength: 1024, description: "value: JSON Pointer into the selected native result; empty selects everything. Examples /objects/0/auto_run or /presets." }),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const CRM_NOTE_BODY_MAX_CHARS = 20000;
|
|
2
2
|
export declare const CRM_NOTE_TITLE_MAX_CHARS = 300;
|
|
3
3
|
export declare const CRM_FILE_LABEL_MAX_CHARS = 300;
|
|
4
|
+
export declare const CRM_FILE_ATTACH_DESCRIPTION = "Attach inline base64 bytes to a CRM record; each call creates a new file and attachment, including identical retries. If a response is lost, inspect the record's files before deciding to retry. Entire request must fit 2 MB; larger originals use upload prepare/complete. No credits.";
|
|
4
5
|
export declare const CRM_NOTE_EDIT_CONTRACT: import("./schema.js").ContractObject<{
|
|
5
6
|
readonly body: import("./schema.js").StringProperty;
|
|
6
7
|
readonly title: {
|
|
@@ -2,6 +2,7 @@ import { bool, enumOf, int, nullable, obj, str } from "./schema.js";
|
|
|
2
2
|
export const CRM_NOTE_BODY_MAX_CHARS = 20_000;
|
|
3
3
|
export const CRM_NOTE_TITLE_MAX_CHARS = 300;
|
|
4
4
|
export const CRM_FILE_LABEL_MAX_CHARS = 300;
|
|
5
|
+
export const CRM_FILE_ATTACH_DESCRIPTION = "Attach inline base64 bytes to a CRM record; each call creates a new file and attachment, including identical retries. If a response is lost, inspect the record's files before deciding to retry. Entire request must fit 2 MB; larger originals use upload prepare/complete. No credits.";
|
|
5
6
|
export const CRM_NOTE_EDIT_CONTRACT = obj({
|
|
6
7
|
body: str({ minLength: 1, maxLength: CRM_NOTE_BODY_MAX_CHARS, description: "Replacement Markdown text." }),
|
|
7
8
|
title: nullable(str({ maxLength: CRM_NOTE_TITLE_MAX_CHARS, description: "Replacement title; null or empty clears." })),
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
import { arr, bool, enumOf, int, nullable, num, obj, str } from "./schema.js";
|
|
3
3
|
import { DATABASE_ATTACH_CONTRACT, DATABASE_MIGRATE_CONTRACT, DATABASE_QUERY_CONTRACT } from "./database.js";
|
|
4
4
|
import { WHATSAPP_DRAFTS_READ_CONTRACT } from "./whatsapp-reads.js";
|
|
5
|
+
import { TABLE_FAVORITE_CONTRACT, TABLE_FAVORITES_LIST_CONTRACT, TABLE_ITEM_RESOLVE_CONTRACT, TABLE_LINK_SUGGEST_CONTRACT, TABLE_RECOVER_PENDING_CONTRACT } from "./table-operations.js";
|
|
5
6
|
import { BILLING_OWNER_READ_CONTRACT } from "./billing-owner-read.js";
|
|
6
7
|
import { COPILOT_SESSIONS_LIST_CONTRACT } from "./copilot-sessions.js";
|
|
8
|
+
import { CRM_FILE_ATTACH_CONTRACT, CRM_FILE_ATTACH_DESCRIPTION } from "./crm-support.js";
|
|
7
9
|
const text = (description) => str(description === undefined ? {} : { description });
|
|
8
10
|
const list = () => arr(str());
|
|
9
11
|
const json = { type: "object", additionalProperties: true };
|
|
@@ -42,7 +44,7 @@ export const CUSTOMER_OPERATIONS = [
|
|
|
42
44
|
operation("context.canonical.get", "/api/cli/context/canonical/get", "POST", "context canonical get", "oxygen_context_canonical_get", "knowledge", "Read the pinned active context asset for a type; present=false means none is set.", { type: text() }, ["type"], { mutates: false }),
|
|
43
45
|
operation("crm.notes.update", "/api/cli/crm/notes/{note_id}", "PATCH", "crm notes update", "oxygen_crm_note_update", "crm", "Edit a CRM note's body, title or pinned state; an empty title clears it.", { body: text(), title: nullable(text()), pinned: bool() }, [], mcpOnly),
|
|
44
46
|
operation("crm.notes.delete", "/api/cli/crm/notes/{note_id}", "DELETE", "crm notes delete", "oxygen_crm_note_delete", "crm", "Delete one CRM note in this workspace.", {}, [], mcpOnly),
|
|
45
|
-
operation("crm.files.attach_inline", "/api/cli/crm/objects/{object}/records/{row_id}/files", "POST", "crm files attach-inline", "oxygen_crm_file_attach", "crm",
|
|
47
|
+
operation("crm.files.attach_inline", "/api/cli/crm/objects/{object}/records/{row_id}/files", "POST", "crm files attach-inline", "oxygen_crm_file_attach", "crm", CRM_FILE_ATTACH_DESCRIPTION, CRM_FILE_ATTACH_CONTRACT.properties, [...(CRM_FILE_ATTACH_CONTRACT.required ?? [])]),
|
|
46
48
|
operation("crm.files.prepare", "/api/cli/crm/objects/{object}/records/{row_id}/files/upload-url", "POST", "crm files prepare-upload", "oxygen_crm_file_prepare_upload", "crm", "Reserve a CRM file upload by exact name, length and SHA-256; returns a scoped upload URL.", { name: text(), byte_length: int({ minimum: 0 }), sha256: text() }, ["name", "byte_length", "sha256"]),
|
|
47
49
|
operation("crm.files.complete", "/api/cli/crm/objects/{object}/records/{row_id}/files/{file_id}/uploaded", "POST", "crm files complete-upload", "oxygen_crm_file_complete_upload", "crm", "Verify a reserved CRM upload and attach it to its record; mismatched bytes remain pending.", { label: text() }),
|
|
48
50
|
operation("crm.files.delete", "/api/cli/crm/files/{attachment_id}", "DELETE", "crm files detach", "oxygen_crm_file_delete", "crm", "Detach a CRM attachment by attachment_id, preserving the stored file.", {}, [], mcpOnly),
|
|
@@ -76,17 +78,17 @@ export const CUSTOMER_OPERATIONS = [
|
|
|
76
78
|
operation("settings.beta.get", "/api/cli/settings/beta-features", "GET", "settings beta-features get", "oxygen_settings_beta_features_get", "workspace", "Read this workspace's beta-navigation opt-in."),
|
|
77
79
|
operation("settings.beta.set", "/api/cli/settings/beta-features", "POST", "settings beta-features set", "oxygen_settings_beta_features_set", "workspace", "Enable or disable beta navigation for this workspace; admin or owner only.", { enabled: bool() }, ["enabled"]),
|
|
78
80
|
operation("spintax.generate", "/api/cli/spintax", "POST", "spintax generate", "oxygen_spintax_generate", "sequences", "Generate spintax for outreach text. Costs exactly 3 credits; failed generation refunds the reservation.", { text: str({ minLength: 1, maxLength: 4000 }), section: str({ maxLength: 80 }) }, ["text"], { spends: true }),
|
|
79
|
-
operation("table_action_items.resolve", "/api/cli/table-action-items/{item_id}/resolve", "POST", "table-actions resolve", "oxygen_table_action_item_resolve", "tables", "Record a verified uncertain Table action outcome
|
|
81
|
+
operation("table_action_items.resolve", "/api/cli/table-action-items/{item_id}/resolve", "POST", "table-actions resolve", "oxygen_table_action_item_resolve", "tables", "Record a human-verified uncertain Table action outcome without repeating it. Use cells resolve for row/column coordinates.", TABLE_ITEM_RESOLVE_CONTRACT.properties, ["outcome"]),
|
|
80
82
|
operation("table_ingestions.append", "/api/cli/table-ingestion-runs/{ingestion_run_id}/items", "POST", "table-ingestions append", "oxygen_table_ingestions_append_items", "runs", "Append bounded ingestion items to an existing run; preserves the run's approved scope.", { items: rows(), max_attempts: int({ minimum: 1 }) }, ["items"], cliOnly),
|
|
81
|
-
operation("tables.favorites.get", "/api/cli/tables/favorite", "GET", "tables favorites", "oxygen_tables_favorites", "tables", "
|
|
82
|
-
operation("tables.favorite.set", "/api/cli/tables/favorite", "POST", "tables favorite", "oxygen_tables_favorite", "tables", "Star
|
|
83
|
+
operation("tables.favorites.get", "/api/cli/tables/favorite", "GET", "tables favorites", "oxygen_tables_favorites", "tables", "Page Table/folder stars (per-member preference; free (0 credits)); use next_cursor. Tool-catalog favorites are separate.", TABLE_FAVORITES_LIST_CONTRACT.properties, [], { generated: { cli: true, mcp: false } }),
|
|
84
|
+
operation("tables.favorite.set", "/api/cli/tables/favorite", "POST", "tables favorite", "oxygen_tables_favorite", "tables", "Star/unstar exactly one table or folder; read back saved per-member preference. Free (0 credits). Tool-catalog favorites are separate.", TABLE_FAVORITE_CONTRACT.properties, ["favorite"]),
|
|
83
85
|
operation("tables.import.csv", "/api/cli/tables/import-csv", "POST", "tables import-csv", "oxygen_tables_import_csv", "tables", "Import inline CSV into a hosted Table through its durable ingestion run. Use staged upload for large files.", { csv_text: text(), csv_base64: text(), table: text(), table_name: text(), project: text(), filename: text(), upsert_key: text(), batch_size: int({ minimum: 1, maximum: 5000 }) }, [], cliOnly),
|
|
84
86
|
operation("tables.import.prepare", "/api/cli/tables/import-url", "POST", "tables import-upload", "oxygen_tables_import_upload", "tables", "Prepare a scoped storage upload for a hosted Table import; uploads and imports are separate, inspectable steps.", { file_name: text(), content_type: text(), byte_length: int({ minimum: 1 }), trace_id: text(), format: enumOf(["csv", "json", "xlsx"]) }, ["file_name", "byte_length"]),
|
|
85
87
|
operation("tables.import.preview", "/api/cli/tables/import-preview", "POST", "tables import-preview", "oxygen_tables_import_preview", "tables", "Preview a staged file's headers, rows and existing-table mapping; writes no imported rows.", { storage_key: text(), file_name: text(), format: enumOf(["csv", "json", "xlsx"]), byte_length: int({ minimum: 1 }), table: text(), upsert_key: text() }, ["storage_key", "byte_length"], { mutates: false }),
|
|
86
88
|
operation("tables.import.staged", "/api/cli/tables/import-staged", "POST", "tables import-staged", "oxygen_tables_import_staged", "tables", "Start a durable hosted import from this workspace's staged file; choose an existing table or create_name.", { table: text(), create_name: text(), project: text(), storage_key: text(), storage_bucket: text(), storage_provider: enumOf(["s3"]), file_name: text(), format: enumOf(["csv", "json", "xlsx"]), sha256: text(), upsert_key: text(), source_key_map: json, byte_length: int({ minimum: 1 }), row_count: int({ minimum: 1 }), max_concurrency: int({ minimum: 1, maximum: 1000 }), source: enumOf(["cli", "mcp", "web"]), batch_size: int({ minimum: 1, maximum: 5000 }) }, ["storage_key", "byte_length"]),
|
|
87
89
|
operation("tables.import.file", "/api/cli/tables/import-file", "POST", "tables import-file", "oxygen_tables_import_file", "tables", "Import small base64 file bytes through the shared multipart import API; use staged upload for large files.", { content_base64: text(), file_name: text(), content_type: text(), table: text(), table_name: text(), project: text(), format: enumOf(["csv", "json", "xlsx"]), sheet: text(), upsert_key: text(), source_key_map: json, source_hash: text(), batch_size: int({ minimum: 1, maximum: 5000 }), max_concurrency: int({ minimum: 1 }) }, ["content_base64", "file_name"], { multipart: { contentField: "content_base64", nameField: "file_name", typeField: "content_type", fileField: "file" } }),
|
|
88
|
-
operation("tables.link.suggest", "/api/cli/tables/link/suggest", "POST", "tables link-suggest", "oxygen_tables_link_suggest", "tables", "
|
|
89
|
-
operation("tables.recover_pending", "/api/cli/tables/recover-pending", "POST", "tables recover-pending", "oxygen_tables_recover_pending", "tables", "
|
|
90
|
+
operation("tables.link.suggest", "/api/cli/tables/link/suggest", "POST", "tables link-suggest", "oxygen_tables_link_suggest", "tables", "Plan column links and matching row counts between Tables; creates no relation. Apply with tables link bulk.", TABLE_LINK_SUGGEST_CONTRACT.properties, ["table", "to"], { mutates: false }),
|
|
91
|
+
operation("tables.recover_pending", "/api/cli/tables/recover-pending", "POST", "tables recover-pending", "oxygen_tables_recover_pending", "tables", "Poll pending BetterContact requests and save recovered phones; no new orders. Does not resume imports.", TABLE_RECOVER_PENDING_CONTRACT.properties, ["table"], { ...mcpOnly, annotations: { openWorldHint: true } }),
|
|
90
92
|
operation("tables.webhooks.create", "/api/cli/tables/webhooks", "POST", "tables webhook create", "oxygen_table_webhook_create", "tables", "Create an inbound Table webhook or platform LinkedIn feed. Optional auto_run is standing permission with explicit or plan-default delivery ceilings.", { table: text(), name: text(), mode: enumOf(["insert", "upsert"]), upsert_key: text(), items_path: text(), event_id_path: text(), event_type_path: text(), occurred_at_path: text(), auth_mode: enumOf(["none", "secret"]), feed_kind: enumOf(["generic", "unipile"]), unipile_account_id: text(), event_types: list(), mapping: text(), auto_run: json }, ["table"], mcpOnly),
|
|
91
93
|
operation("tables.webhooks.update", "/api/cli/tables/webhooks", "PATCH", "tables webhook update", "oxygen_table_webhook_update", "tables", "Edit a Table webhook's name, state or standing auto_run; auth_mode=secret rotates its secret and returns it once.", { endpoint_id: text(), name: text(), status: enumOf(["active", "disabled"]), auth_mode: enumOf(["none", "secret"]), auto_run: json, clear_auto_run: bool() }, ["endpoint_id"], mcpOnly),
|
|
92
94
|
operation("whatsapp.draft", "/api/cli/whatsapp/draft", "POST", "whatsapp draft", "oxygen_whatsapp_draft", "inbox", "Generate a WhatsApp reply draft in the workspace voice, or approve a reviewed draft for an existing chat. Draft generation uses managed AI credits.", { conversation_id: text(), goal: text(), row_id: text(), object: text(), approved: bool(), draft_id: text(), text: text() }, ["conversation_id"], { ...cliOnly, spends: true }),
|
|
@@ -9,6 +9,7 @@ import { str } from "./schema.js";
|
|
|
9
9
|
import { SENDER_LIMITS_SET_OPERATION } from "./sender-limits.js";
|
|
10
10
|
import { WORKSPACE_PAGES_GET_OPERATION, WORKSPACE_PAGES_UPDATE_OPERATION } from "./workspace-pages.js";
|
|
11
11
|
import { BROWSER_OPERATIONS } from "./browser-operations.js";
|
|
12
|
+
import { TABLE_FEED_UPDATE_OPERATION } from "./table-feed-update.js";
|
|
12
13
|
import { CUSTOMER_OPERATIONS } from "./customer-operations.js";
|
|
13
14
|
/** The route with its `{param}` segments filled in, each URL-encoded. */
|
|
14
15
|
export function operationPath(spec, params) {
|
|
@@ -79,6 +80,6 @@ export function operationFormData(spec, body) {
|
|
|
79
80
|
}
|
|
80
81
|
return form;
|
|
81
82
|
}
|
|
82
|
-
export const OPERATION_SPECS = [SENDER_LIMITS_SET_OPERATION, CONNECTOR_UPDATE_OPERATION, CONNECTOR_EVENTS_REVOKE_OPERATION, WORKSPACE_PAGES_GET_OPERATION, WORKSPACE_PAGES_UPDATE_OPERATION, ...CUSTOMER_OPERATIONS, ...BROWSER_OPERATIONS];
|
|
83
|
+
export const OPERATION_SPECS = [SENDER_LIMITS_SET_OPERATION, CONNECTOR_UPDATE_OPERATION, CONNECTOR_EVENTS_REVOKE_OPERATION, WORKSPACE_PAGES_GET_OPERATION, WORKSPACE_PAGES_UPDATE_OPERATION, TABLE_FEED_UPDATE_OPERATION, ...CUSTOMER_OPERATIONS, ...BROWSER_OPERATIONS];
|
|
83
84
|
export const CLI_OPERATIONS = [...CUSTOMER_OPERATIONS, ...BROWSER_OPERATIONS].filter((spec) => spec.generated?.cli !== false);
|
|
84
85
|
export const MCP_OPERATIONS = [...CUSTOMER_OPERATIONS, ...BROWSER_OPERATIONS].filter((spec) => spec.generated?.mcp !== false);
|
|
@@ -55,6 +55,9 @@ export interface OneOfProperty {
|
|
|
55
55
|
description?: string;
|
|
56
56
|
}
|
|
57
57
|
export type JsonProperty = {
|
|
58
|
+
type?: never;
|
|
59
|
+
description?: string;
|
|
60
|
+
} | {
|
|
58
61
|
$ref: string;
|
|
59
62
|
} | StringProperty | NumberProperty | BooleanProperty | NullProperty | ObjectProperty | ArrayProperty | OneOfProperty;
|
|
60
63
|
/** The top level of a contract: a closed object. */
|
|
@@ -88,6 +91,11 @@ export declare function num(options?: NumberOptions): {
|
|
|
88
91
|
"x-clamp"?: true;
|
|
89
92
|
};
|
|
90
93
|
export declare function bool(options?: Described): BooleanProperty;
|
|
94
|
+
/** Any JSON value, including null; used for native cell-result values. */
|
|
95
|
+
export declare function jsonValue(options?: Described): {
|
|
96
|
+
type?: never;
|
|
97
|
+
description?: string;
|
|
98
|
+
};
|
|
91
99
|
export declare function str(options?: Described & {
|
|
92
100
|
minLength?: number;
|
|
93
101
|
maxLength?: number;
|
|
@@ -31,6 +31,10 @@ export function num(options) {
|
|
|
31
31
|
export function bool(options = {}) {
|
|
32
32
|
return described({ type: "boolean" }, options.description);
|
|
33
33
|
}
|
|
34
|
+
/** Any JSON value, including null; used for native cell-result values. */
|
|
35
|
+
export function jsonValue(options = {}) {
|
|
36
|
+
return { ...options };
|
|
37
|
+
}
|
|
34
38
|
export function str(options = {}) {
|
|
35
39
|
const { description, ...rest } = options;
|
|
36
40
|
return described({ type: "string", ...rest }, description);
|
|
@@ -172,6 +176,8 @@ function walkValue(schema, value, path, walk) {
|
|
|
172
176
|
walk.issues.push({ path, message: `${path} does not match any accepted shape.` });
|
|
173
177
|
return value;
|
|
174
178
|
}
|
|
179
|
+
if (schema.type === undefined)
|
|
180
|
+
return value;
|
|
175
181
|
if (schema.type === "null") {
|
|
176
182
|
if (value !== null)
|
|
177
183
|
walk.issues.push({ path, message: `${path} must be null.` });
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export declare const SEQUENCE_ANALYTICS_READ_CONTRACT: import("./schema.js").ContractObject<{
|
|
2
|
+
readonly projection: {
|
|
3
|
+
type: "string";
|
|
4
|
+
enum: readonly ("full" | "summary" | "value")[];
|
|
5
|
+
description?: string;
|
|
6
|
+
};
|
|
7
|
+
readonly path: import("./schema.js").StringProperty;
|
|
8
|
+
readonly value_cursor: import("./schema.js").StringProperty;
|
|
9
|
+
readonly max_chars: {
|
|
10
|
+
type: "integer";
|
|
11
|
+
description?: string;
|
|
12
|
+
minimum?: number;
|
|
13
|
+
maximum?: number;
|
|
14
|
+
"x-clamp"?: true;
|
|
15
|
+
};
|
|
16
|
+
readonly range: {
|
|
17
|
+
type: "string";
|
|
18
|
+
enum: readonly ("14d" | "180d" | "28d" | "30d" | "365d" | "7d" | "90d" | "all")[];
|
|
19
|
+
description?: string;
|
|
20
|
+
};
|
|
21
|
+
readonly from: import("./schema.js").StringProperty;
|
|
22
|
+
readonly to: import("./schema.js").StringProperty;
|
|
23
|
+
readonly sequence: import("./schema.js").StringProperty;
|
|
24
|
+
readonly campaigns: import("./schema.js").StringProperty;
|
|
25
|
+
readonly senders: import("./schema.js").StringProperty;
|
|
26
|
+
}, never>;
|
|
27
|
+
/** Preserve shipped query precedence, repeated/CSV senders, and native range
|
|
28
|
+
* coercion. Only opt-in representation controls are separately validated. */
|
|
29
|
+
export declare function sequenceAnalyticsSelection(params: URLSearchParams): {
|
|
30
|
+
range: {
|
|
31
|
+
preset: string | null;
|
|
32
|
+
from: string | null;
|
|
33
|
+
to: string | null;
|
|
34
|
+
};
|
|
35
|
+
sequenceId: string | null;
|
|
36
|
+
sequenceIds: string[];
|
|
37
|
+
senders: string[];
|
|
38
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { enumOf, obj, str } from "./schema.js";
|
|
2
|
+
import { STORED_READ_WINDOW_FIELDS } from "./stored-read-window.js";
|
|
3
|
+
export const SEQUENCE_ANALYTICS_READ_CONTRACT = obj({
|
|
4
|
+
range: enumOf(["7d", "14d", "28d", "30d", "90d", "180d", "365d", "all"], { description: "Default 14d. all starts at oldest selected campaign, at most 1830 days; daily<=92 days, weekly<=550, else monthly." }),
|
|
5
|
+
from: str({ description: "Custom start date (YYYY-MM-DD)." }),
|
|
6
|
+
to: str({ description: "Custom end date (YYYY-MM-DD)." }),
|
|
7
|
+
sequence: str({ description: "Exact campaign id/slug, including outside latest 500. Single scope ignores campaigns; includes sender/message performance." }),
|
|
8
|
+
campaigns: str({ description: "CSV ids/slugs: org totals, series, email attribution and operational summary only. Roster/fleet/per-campaign stats retain latest 500; ignored with sequence." }),
|
|
9
|
+
senders: str({ description: "CSV analytics.senders keys or sender/profile ids (oxygen_senders_profiles_list). Narrows counts/funnels/series/attribution/drilldowns, not roster or operational health/work." }),
|
|
10
|
+
...STORED_READ_WINDOW_FIELDS,
|
|
11
|
+
});
|
|
12
|
+
/** Preserve shipped query precedence, repeated/CSV senders, and native range
|
|
13
|
+
* coercion. Only opt-in representation controls are separately validated. */
|
|
14
|
+
export function sequenceAnalyticsSelection(params) {
|
|
15
|
+
const csv = (values) => values.flatMap(value => value.split(",")).map(value => value.trim()).filter(value => value.length > 0);
|
|
16
|
+
return {
|
|
17
|
+
range: { preset: params.get("range"), from: params.get("from"), to: params.get("to") },
|
|
18
|
+
sequenceId: params.get("sequence") ?? params.get("sequence_id") ?? null,
|
|
19
|
+
sequenceIds: csv([params.get("campaigns") ?? params.get("sequences") ?? ""]),
|
|
20
|
+
senders: csv(params.getAll("senders")),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/** Native Table feed PATCH grammar. Scheduling and credit authority remain server-owned. */
|
|
2
|
+
import { type ContractObject } from "./schema.js";
|
|
3
|
+
import type { OperationSpec } from "./operations.js";
|
|
4
|
+
export declare const TABLE_FEED_LANE_CONTRACT: ContractObject<{
|
|
5
|
+
readonly tool_id: import("./schema.js").StringProperty;
|
|
6
|
+
readonly request: {
|
|
7
|
+
type: "object";
|
|
8
|
+
additionalProperties: boolean;
|
|
9
|
+
};
|
|
10
|
+
readonly rows_path: {
|
|
11
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
12
|
+
description?: string;
|
|
13
|
+
};
|
|
14
|
+
readonly row_mapping: {
|
|
15
|
+
oneOf: [{
|
|
16
|
+
type: "object";
|
|
17
|
+
additionalProperties: boolean;
|
|
18
|
+
}, import("./schema.js").NullProperty];
|
|
19
|
+
description?: string;
|
|
20
|
+
};
|
|
21
|
+
readonly cursor_path: {
|
|
22
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
23
|
+
description?: string;
|
|
24
|
+
};
|
|
25
|
+
readonly cursor_request_key: {
|
|
26
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
27
|
+
description?: string;
|
|
28
|
+
};
|
|
29
|
+
}, "request" | "tool_id">;
|
|
30
|
+
export declare const TABLE_FEED_ROUTE_CONTRACT: ContractObject<{
|
|
31
|
+
readonly tool_id: import("./schema.js").StringProperty;
|
|
32
|
+
readonly request: {
|
|
33
|
+
type: "object";
|
|
34
|
+
additionalProperties: boolean;
|
|
35
|
+
};
|
|
36
|
+
readonly rows_path: {
|
|
37
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
38
|
+
description?: string;
|
|
39
|
+
};
|
|
40
|
+
readonly row_mapping: {
|
|
41
|
+
oneOf: [{
|
|
42
|
+
type: "object";
|
|
43
|
+
additionalProperties: boolean;
|
|
44
|
+
}, import("./schema.js").NullProperty];
|
|
45
|
+
description?: string;
|
|
46
|
+
};
|
|
47
|
+
readonly cursor_path: {
|
|
48
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
49
|
+
description?: string;
|
|
50
|
+
};
|
|
51
|
+
readonly cursor_request_key: {
|
|
52
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
53
|
+
description?: string;
|
|
54
|
+
};
|
|
55
|
+
readonly tool_ids: import("./schema.js").ArrayProperty<import("./schema.js").StringProperty>;
|
|
56
|
+
readonly lanes: import("./schema.js").ArrayProperty<ContractObject<{
|
|
57
|
+
readonly tool_id: import("./schema.js").StringProperty;
|
|
58
|
+
readonly request: {
|
|
59
|
+
type: "object";
|
|
60
|
+
additionalProperties: boolean;
|
|
61
|
+
};
|
|
62
|
+
readonly rows_path: {
|
|
63
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
64
|
+
description?: string;
|
|
65
|
+
};
|
|
66
|
+
readonly row_mapping: {
|
|
67
|
+
oneOf: [{
|
|
68
|
+
type: "object";
|
|
69
|
+
additionalProperties: boolean;
|
|
70
|
+
}, import("./schema.js").NullProperty];
|
|
71
|
+
description?: string;
|
|
72
|
+
};
|
|
73
|
+
readonly cursor_path: {
|
|
74
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
75
|
+
description?: string;
|
|
76
|
+
};
|
|
77
|
+
readonly cursor_request_key: {
|
|
78
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
79
|
+
description?: string;
|
|
80
|
+
};
|
|
81
|
+
}, "request" | "tool_id">>;
|
|
82
|
+
readonly max_pages: {
|
|
83
|
+
type: "integer";
|
|
84
|
+
description?: string;
|
|
85
|
+
minimum?: number;
|
|
86
|
+
maximum?: number;
|
|
87
|
+
"x-clamp"?: true;
|
|
88
|
+
};
|
|
89
|
+
readonly upsert_key: {
|
|
90
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
91
|
+
description?: string;
|
|
92
|
+
};
|
|
93
|
+
}, "request" | "tool_id">;
|
|
94
|
+
export declare const TABLE_FEED_GET_OPTIONS_CONTRACT: ContractObject<{
|
|
95
|
+
readonly include_route: import("./schema.js").BooleanProperty;
|
|
96
|
+
}, never>;
|
|
97
|
+
export declare const TABLE_FEED_UPDATE_CONTRACT: ContractObject<{
|
|
98
|
+
readonly feed: import("./schema.js").StringProperty;
|
|
99
|
+
readonly name: import("./schema.js").StringProperty;
|
|
100
|
+
readonly status: {
|
|
101
|
+
type: "string";
|
|
102
|
+
enum: readonly ("active" | "disabled")[];
|
|
103
|
+
description?: string;
|
|
104
|
+
};
|
|
105
|
+
readonly run_state: {
|
|
106
|
+
type: "string";
|
|
107
|
+
enum: readonly ("error" | "exhausted" | "idle" | "running")[];
|
|
108
|
+
description?: string;
|
|
109
|
+
};
|
|
110
|
+
readonly sync: ContractObject<{
|
|
111
|
+
readonly every: {
|
|
112
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
113
|
+
description?: string;
|
|
114
|
+
};
|
|
115
|
+
readonly max_credits_per_cycle: {
|
|
116
|
+
readonly type: "number";
|
|
117
|
+
readonly exclusiveMinimum: 0;
|
|
118
|
+
readonly description: "Future-cycle ceiling; configuration spends nothing.";
|
|
119
|
+
};
|
|
120
|
+
readonly max_rows_per_cycle: {
|
|
121
|
+
type: "integer";
|
|
122
|
+
description?: string;
|
|
123
|
+
minimum?: number;
|
|
124
|
+
maximum?: number;
|
|
125
|
+
"x-clamp"?: true;
|
|
126
|
+
};
|
|
127
|
+
}, "every" | "max_credits_per_cycle" | "max_rows_per_cycle">;
|
|
128
|
+
readonly route: {
|
|
129
|
+
readonly type: "object";
|
|
130
|
+
readonly additionalProperties: false;
|
|
131
|
+
readonly properties: {
|
|
132
|
+
readonly tool_id: import("./schema.js").StringProperty;
|
|
133
|
+
readonly request: {
|
|
134
|
+
type: "object";
|
|
135
|
+
additionalProperties: boolean;
|
|
136
|
+
};
|
|
137
|
+
readonly rows_path: {
|
|
138
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
139
|
+
description?: string;
|
|
140
|
+
};
|
|
141
|
+
readonly row_mapping: {
|
|
142
|
+
oneOf: [{
|
|
143
|
+
type: "object";
|
|
144
|
+
additionalProperties: boolean;
|
|
145
|
+
}, import("./schema.js").NullProperty];
|
|
146
|
+
description?: string;
|
|
147
|
+
};
|
|
148
|
+
readonly cursor_path: {
|
|
149
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
150
|
+
description?: string;
|
|
151
|
+
};
|
|
152
|
+
readonly cursor_request_key: {
|
|
153
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
154
|
+
description?: string;
|
|
155
|
+
};
|
|
156
|
+
readonly tool_ids: import("./schema.js").ArrayProperty<import("./schema.js").StringProperty>;
|
|
157
|
+
readonly lanes: import("./schema.js").ArrayProperty<ContractObject<{
|
|
158
|
+
readonly tool_id: import("./schema.js").StringProperty;
|
|
159
|
+
readonly request: {
|
|
160
|
+
type: "object";
|
|
161
|
+
additionalProperties: boolean;
|
|
162
|
+
};
|
|
163
|
+
readonly rows_path: {
|
|
164
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
165
|
+
description?: string;
|
|
166
|
+
};
|
|
167
|
+
readonly row_mapping: {
|
|
168
|
+
oneOf: [{
|
|
169
|
+
type: "object";
|
|
170
|
+
additionalProperties: boolean;
|
|
171
|
+
}, import("./schema.js").NullProperty];
|
|
172
|
+
description?: string;
|
|
173
|
+
};
|
|
174
|
+
readonly cursor_path: {
|
|
175
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
176
|
+
description?: string;
|
|
177
|
+
};
|
|
178
|
+
readonly cursor_request_key: {
|
|
179
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
180
|
+
description?: string;
|
|
181
|
+
};
|
|
182
|
+
}, "request" | "tool_id">>;
|
|
183
|
+
readonly max_pages: {
|
|
184
|
+
type: "integer";
|
|
185
|
+
description?: string;
|
|
186
|
+
minimum?: number;
|
|
187
|
+
maximum?: number;
|
|
188
|
+
"x-clamp"?: true;
|
|
189
|
+
};
|
|
190
|
+
readonly upsert_key: {
|
|
191
|
+
oneOf: [import("./schema.js").StringProperty, import("./schema.js").NullProperty];
|
|
192
|
+
description?: string;
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
readonly required?: readonly ("request" | "tool_id")[];
|
|
196
|
+
readonly description: "Full frozen route from feeds_get(include_route=true). Replacement resets cursor/error. Scheduled replacements require one executable lane; distinct fallbacks require no cadence.";
|
|
197
|
+
};
|
|
198
|
+
readonly filters: {
|
|
199
|
+
type: "object";
|
|
200
|
+
additionalProperties: boolean;
|
|
201
|
+
};
|
|
202
|
+
readonly intent_id: import("./schema.js").StringProperty;
|
|
203
|
+
readonly input_shape: import("./schema.js").StringProperty;
|
|
204
|
+
readonly route_id: import("./schema.js").StringProperty;
|
|
205
|
+
readonly registry_version: import("./schema.js").StringProperty;
|
|
206
|
+
readonly source_prompt: import("./schema.js").StringProperty;
|
|
207
|
+
readonly approved: import("./schema.js").BooleanProperty;
|
|
208
|
+
}, "feed">;
|
|
209
|
+
/** New surfaces refuse provenance edits the native PATCH would otherwise ignore. */
|
|
210
|
+
export declare function tableFeedUpdateIssues(args: Record<string, unknown>): string[];
|
|
211
|
+
export declare const TABLE_FEED_UPDATE_OPERATION: OperationSpec<ContractObject>;
|
|
212
|
+
/** The existing native PATCH scope comparison, separate from configuration cost. */
|
|
213
|
+
export declare function tableFeedUpdateScopeChange(args: Record<string, unknown>, current: {
|
|
214
|
+
every: string | null;
|
|
215
|
+
maxCredits: number | null;
|
|
216
|
+
}): {
|
|
217
|
+
every: string | null;
|
|
218
|
+
raisesCap: boolean;
|
|
219
|
+
replacesSource: boolean;
|
|
220
|
+
changesCadence: boolean;
|
|
221
|
+
needsReapproval: boolean;
|
|
222
|
+
};
|