@imbrace/cli 0.4.0 → 0.5.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/commands/ai-agent/create.d.ts +1 -0
- package/dist/commands/ai-agent/create.js +5 -0
- package/dist/commands/document-ai/create.d.ts +18 -0
- package/dist/commands/document-ai/create.js +76 -0
- package/dist/commands/document-ai/delete.d.ts +13 -0
- package/dist/commands/document-ai/delete.js +41 -0
- package/dist/commands/document-ai/get.d.ts +12 -0
- package/dist/commands/document-ai/get.js +45 -0
- package/dist/commands/document-ai/list.d.ts +11 -0
- package/dist/commands/document-ai/list.js +42 -0
- package/dist/commands/document-ai/process.d.ts +21 -0
- package/dist/commands/document-ai/process.js +58 -0
- package/dist/commands/document-ai/suggest-schema.d.ts +12 -0
- package/dist/commands/document-ai/suggest-schema.js +37 -0
- package/dist/commands/document-ai/update.d.ts +20 -0
- package/dist/commands/document-ai/update.js +76 -0
- package/dist/commands/guardrail/create.d.ts +19 -0
- package/dist/commands/guardrail/create.js +69 -0
- package/dist/commands/guardrail/delete.d.ts +13 -0
- package/dist/commands/guardrail/delete.js +41 -0
- package/dist/commands/guardrail/get.d.ts +12 -0
- package/dist/commands/guardrail/get.js +42 -0
- package/dist/commands/guardrail/list.d.ts +9 -0
- package/dist/commands/guardrail/list.js +40 -0
- package/dist/commands/guardrail/update.d.ts +20 -0
- package/dist/commands/guardrail/update.js +49 -0
- package/dist/commands/orchestrator/create.d.ts +18 -0
- package/dist/commands/orchestrator/create.js +68 -0
- package/dist/commands/orchestrator/delete.d.ts +13 -0
- package/dist/commands/orchestrator/delete.js +41 -0
- package/dist/commands/orchestrator/get.d.ts +12 -0
- package/dist/commands/orchestrator/get.js +52 -0
- package/dist/commands/orchestrator/list.d.ts +9 -0
- package/dist/commands/orchestrator/list.js +41 -0
- package/dist/lib/ai-agent.d.ts +8 -0
- package/dist/lib/ai-agent.js +63 -6
- package/llms.txt +55 -0
- package/package.json +11 -2
|
@@ -9,6 +9,7 @@ export default class AiAgentCreate extends BaseCommand {
|
|
|
9
9
|
model: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
10
|
"provider-id": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
11
|
mode: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
"agent-type": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
13
|
temperature: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
14
|
personality: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
15
|
"core-task": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -18,6 +18,10 @@ export default class AiAgentCreate extends BaseCommand {
|
|
|
18
18
|
model: Flags.string({ description: "LLM model (e.g. gpt-4o, qwen3.5-27b). Default: gpt-4o" }),
|
|
19
19
|
"provider-id": Flags.string({ description: "LLM provider ID. Default 'system'. Use 'imbrace ai-agent list-providers' to discover." }),
|
|
20
20
|
mode: Flags.string({ description: "Agent mode (default: standard)", options: ["standard", "advanced"] }),
|
|
21
|
+
"agent-type": Flags.string({
|
|
22
|
+
description: "Agent type (default: agent). For Document AI, use `imbrace document-ai create` instead.",
|
|
23
|
+
options: ["agent", "assistant", "conversational", "workflow"],
|
|
24
|
+
}),
|
|
21
25
|
temperature: Flags.string({ description: "Model temperature 0.0-2.0 (default: 0.1). Lower = deterministic, higher = creative." }),
|
|
22
26
|
// Behavior Settings (UI tab)
|
|
23
27
|
personality: Flags.string({ description: "Agent personality / role (e.g. 'You are a friendly support rep')" }),
|
|
@@ -57,6 +61,7 @@ export default class AiAgentCreate extends BaseCommand {
|
|
|
57
61
|
...(flags.model && { model: flags.model }),
|
|
58
62
|
...(flags["provider-id"] && { provider_id: flags["provider-id"] }),
|
|
59
63
|
...(flags.mode && { mode: flags.mode }),
|
|
64
|
+
...(flags["agent-type"] && { agent_type: flags["agent-type"] }),
|
|
60
65
|
...(flags.temperature && { temperature: parseFloat(flags.temperature) }),
|
|
61
66
|
...(flags.personality && { personality_role: flags.personality }),
|
|
62
67
|
...(flags["core-task"] && { core_task: flags["core-task"] }),
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class DocumentAiCreate extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
instructions: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
model: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
"provider-id": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
schema: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
"schema-file": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
"workflow-name": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
|
+
"id-only": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
};
|
|
17
|
+
run(): Promise<void>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { BaseCommand } from "../../base-command.js";
|
|
4
|
+
import { input } from "@inquirer/prompts";
|
|
5
|
+
import { getClient } from "../../lib/client.js";
|
|
6
|
+
export default class DocumentAiCreate extends BaseCommand {
|
|
7
|
+
static description = "Create a Document AI agent (extracts structured JSON from PDFs/images)";
|
|
8
|
+
static examples = [
|
|
9
|
+
'imbrace document-ai create --name "Invoice Extractor" --instructions "Extract invoice fields. Dates as YYYY-MM-DD." --model gpt-4o --schema \'{"invoice_number":{"type":"string"},"total":{"type":"number"}}\' --json',
|
|
10
|
+
'imbrace document-ai create --name "Receipt" --instructions "Extract receipt." --model gpt-4o --schema-file ./schema.json --id-only',
|
|
11
|
+
];
|
|
12
|
+
static flags = {
|
|
13
|
+
name: Flags.string({ char: "n", description: "Agent display name" }),
|
|
14
|
+
instructions: Flags.string({ char: "i", description: "System prompt governing extraction logic" }),
|
|
15
|
+
model: Flags.string({ description: "LLM model ID (e.g. gpt-4o, qwen3.5-27b)" }),
|
|
16
|
+
"provider-id": Flags.string({ description: "Provider UUID (use 'system' for org default)" }),
|
|
17
|
+
schema: Flags.string({ description: "JSON schema for fields (inline). Either this or --schema-file." }),
|
|
18
|
+
"schema-file": Flags.string({ description: "Path to JSON schema file" }),
|
|
19
|
+
description: Flags.string({ char: "d", description: "Agent description" }),
|
|
20
|
+
"workflow-name": Flags.string({ description: "Internal workflow name (default: 'document_extraction')" }),
|
|
21
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
22
|
+
"id-only": Flags.boolean({ description: "Print only the new agent ID (pipe-friendly)" }),
|
|
23
|
+
};
|
|
24
|
+
async run() {
|
|
25
|
+
const { flags } = await this.parse(DocumentAiCreate);
|
|
26
|
+
const nonInteractive = flags.json || flags["id-only"];
|
|
27
|
+
const name = flags.name ?? (nonInteractive ? this.error("--name is required with --json or --id-only") : await input({ message: "Agent name:" }));
|
|
28
|
+
const instructions = flags.instructions ?? (nonInteractive ? this.error("--instructions is required with --json or --id-only") : await input({ message: "Instructions:" }));
|
|
29
|
+
const model = flags.model ?? (nonInteractive ? this.error("--model is required with --json or --id-only") : await input({ message: "Model (e.g. gpt-4o):" }));
|
|
30
|
+
let schema;
|
|
31
|
+
if (flags.schema) {
|
|
32
|
+
try {
|
|
33
|
+
schema = JSON.parse(flags.schema);
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
this.error(`--schema is not valid JSON: ${e.message}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (flags["schema-file"]) {
|
|
40
|
+
try {
|
|
41
|
+
schema = JSON.parse(readFileSync(flags["schema-file"], "utf8"));
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
this.error(`--schema-file is not valid JSON: ${e.message}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const client = getClient();
|
|
49
|
+
const data = await client.documentAi.createAgent({
|
|
50
|
+
name,
|
|
51
|
+
instructions,
|
|
52
|
+
model_id: model,
|
|
53
|
+
...(flags["provider-id"] && { provider_id: flags["provider-id"] }),
|
|
54
|
+
...(schema && { schema }),
|
|
55
|
+
...(flags.description && { description: flags.description }),
|
|
56
|
+
...(flags["workflow-name"] && { workflow_name: flags["workflow-name"] }),
|
|
57
|
+
});
|
|
58
|
+
if (flags["id-only"]) {
|
|
59
|
+
this.log(data?._id ?? data?.id ?? "");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const message = `Document AI Agent "${name}" created`;
|
|
63
|
+
if (flags.json) {
|
|
64
|
+
this.log(JSON.stringify({ ok: true, message, data }, null, 2));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
this.log(`\n✅ ${message}`);
|
|
68
|
+
if (data?._id || data?.id)
|
|
69
|
+
this.log(` ID: ${data._id || data.id}`);
|
|
70
|
+
this.log("");
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
this.error(`Failed: ${error.message}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class DocumentAiDelete extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { confirm, input } from "@inquirer/prompts";
|
|
4
|
+
import { getClient } from "../../lib/client.js";
|
|
5
|
+
export default class DocumentAiDelete extends BaseCommand {
|
|
6
|
+
static description = "Delete a Document AI agent";
|
|
7
|
+
static examples = [
|
|
8
|
+
"imbrace document-ai delete <agentId> --yes --json",
|
|
9
|
+
];
|
|
10
|
+
static args = {
|
|
11
|
+
id: Args.string({ description: "Document AI agent ID" }),
|
|
12
|
+
};
|
|
13
|
+
static flags = {
|
|
14
|
+
yes: Flags.boolean({ char: "y", description: "Skip confirmation" }),
|
|
15
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
16
|
+
};
|
|
17
|
+
async run() {
|
|
18
|
+
const { args, flags } = await this.parse(DocumentAiDelete);
|
|
19
|
+
const id = args.id ?? (flags.json ? this.error("ID is required") : await input({ message: "Agent ID:" }));
|
|
20
|
+
if (!flags.yes && !flags.json) {
|
|
21
|
+
const ok = await confirm({ message: `Delete Document AI agent ${id}?`, default: false });
|
|
22
|
+
if (!ok) {
|
|
23
|
+
this.log("Cancelled.");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const client = getClient();
|
|
29
|
+
await client.documentAi.deleteAgent(id);
|
|
30
|
+
const message = "Document AI Agent deleted";
|
|
31
|
+
if (flags.json) {
|
|
32
|
+
this.log(JSON.stringify({ ok: true, message }, null, 2));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this.log(`\n✅ ${message}\n`);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
this.error(`Failed: ${error.message}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class DocumentAiGet extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { input } from "@inquirer/prompts";
|
|
4
|
+
import { getClient } from "../../lib/client.js";
|
|
5
|
+
export default class DocumentAiGet extends BaseCommand {
|
|
6
|
+
static description = "Get details of a Document AI agent (including extraction schema)";
|
|
7
|
+
static examples = [
|
|
8
|
+
"imbrace document-ai get <agentId>",
|
|
9
|
+
"imbrace document-ai get <agentId> --json",
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
id: Args.string({ description: "Document AI agent ID" }),
|
|
13
|
+
};
|
|
14
|
+
static flags = {
|
|
15
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
16
|
+
};
|
|
17
|
+
async run() {
|
|
18
|
+
const { args, flags } = await this.parse(DocumentAiGet);
|
|
19
|
+
const id = args.id ?? (flags.json ? this.error("ID is required") : await input({ message: "Agent ID:" }));
|
|
20
|
+
try {
|
|
21
|
+
const client = getClient();
|
|
22
|
+
const data = await client.documentAi.getAgent(id);
|
|
23
|
+
if (flags.json) {
|
|
24
|
+
this.log(JSON.stringify({ ok: true, data }, null, 2));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const a = data || {};
|
|
28
|
+
this.log(`\n ID: ${a._id || a.id || ""}`);
|
|
29
|
+
this.log(` Name: ${a.name || ""}`);
|
|
30
|
+
this.log(` Model: ${a.model_id || ""}`);
|
|
31
|
+
this.log(` Provider ID: ${a.provider_id || ""}`);
|
|
32
|
+
this.log(` Workflow: ${a.workflow_name || ""}`);
|
|
33
|
+
if (a.data_schema) {
|
|
34
|
+
this.log(` Schema fields: ${Object.keys(a.data_schema).join(", ")}`);
|
|
35
|
+
}
|
|
36
|
+
if (a.instructions) {
|
|
37
|
+
this.log(` Instructions: ${String(a.instructions).slice(0, 80)}${a.instructions.length > 80 ? "..." : ""}`);
|
|
38
|
+
}
|
|
39
|
+
this.log("");
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
this.error(`Failed: ${error.message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class DocumentAiList extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
search: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { getClient } from "../../lib/client.js";
|
|
4
|
+
export default class DocumentAiList extends BaseCommand {
|
|
5
|
+
static description = "List Document AI agents (filter by name)";
|
|
6
|
+
static examples = [
|
|
7
|
+
"imbrace document-ai list",
|
|
8
|
+
"imbrace document-ai list --search invoice --json",
|
|
9
|
+
];
|
|
10
|
+
static flags = {
|
|
11
|
+
search: Flags.string({ char: "s", description: "Filter by name (case-insensitive substring)" }),
|
|
12
|
+
all: Flags.boolean({ description: "Include non-Document-AI agents (default: only document_ai type)" }),
|
|
13
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
14
|
+
};
|
|
15
|
+
async run() {
|
|
16
|
+
const { flags } = await this.parse(DocumentAiList);
|
|
17
|
+
try {
|
|
18
|
+
const client = getClient();
|
|
19
|
+
const data = await client.documentAi.listAgents({
|
|
20
|
+
documentAiOnly: !flags.all,
|
|
21
|
+
...(flags.search && { nameContains: flags.search }),
|
|
22
|
+
});
|
|
23
|
+
if (flags.json) {
|
|
24
|
+
this.log(JSON.stringify({ ok: true, count: data.length, data }, null, 2));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
this.log(`\n Found ${data.length} Document AI agent(s):\n`);
|
|
28
|
+
this.log(" ID NAME MODEL");
|
|
29
|
+
this.log(" ────────────────────────────────────────────────────────────────────────────");
|
|
30
|
+
for (const a of data) {
|
|
31
|
+
const id = (a._id || a.id || "").padEnd(38);
|
|
32
|
+
const name = (a.name || "").padEnd(28);
|
|
33
|
+
const model = a.model_id || "";
|
|
34
|
+
this.log(` ${id} ${name} ${model}`);
|
|
35
|
+
}
|
|
36
|
+
this.log("");
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
this.error(`Failed: ${error.message}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class DocumentAiProcess extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
"agent-id": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
url: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
"org-id": import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
model: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
instructions: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
"board-id": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
language: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
"additional-instructions": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
"chunk-size": import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
"max-concurrent": import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
"max-retries": import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
"enhanced-processing": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
18
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
};
|
|
20
|
+
run(): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { getClient } from "../../lib/client.js";
|
|
4
|
+
export default class DocumentAiProcess extends BaseCommand {
|
|
5
|
+
static description = "Run a Document AI agent on a PDF/image URL — returns the extracted JSON";
|
|
6
|
+
static examples = [
|
|
7
|
+
"imbrace document-ai process --agent-id <id> --url https://example.com/invoice.pdf --org-id org_xxx --json",
|
|
8
|
+
"imbrace document-ai process --url https://example.com/doc.pdf --org-id org_xxx --model gpt-4o --instructions 'Extract X' --json",
|
|
9
|
+
];
|
|
10
|
+
static flags = {
|
|
11
|
+
"agent-id": Flags.string({ description: "Agent ID. If provided, uses agent's model + instructions (overridden by --model/--instructions)." }),
|
|
12
|
+
url: Flags.string({ description: "URL of the document to extract", required: true }),
|
|
13
|
+
"org-id": Flags.string({ description: "Organization ID (sent in body and header)", required: true }),
|
|
14
|
+
model: Flags.string({ description: "Override agent's model. Required if --agent-id not provided." }),
|
|
15
|
+
instructions: Flags.string({ char: "i", description: "Override agent's instructions" }),
|
|
16
|
+
"board-id": Flags.string({ description: "Board ID to write extracted records into" }),
|
|
17
|
+
language: Flags.string({ description: "Document language hint" }),
|
|
18
|
+
"additional-instructions": Flags.string({ description: "Extra per-call instructions appended to agent's prompt" }),
|
|
19
|
+
"chunk-size": Flags.integer({ description: "Chunk size for large documents" }),
|
|
20
|
+
"max-concurrent": Flags.integer({ description: "Max concurrent chunks" }),
|
|
21
|
+
"max-retries": Flags.integer({ description: "Max retries on failure" }),
|
|
22
|
+
"enhanced-processing": Flags.boolean({ description: "Use enhanced processing pipeline", allowNo: true }),
|
|
23
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
24
|
+
};
|
|
25
|
+
async run() {
|
|
26
|
+
const { flags } = await this.parse(DocumentAiProcess);
|
|
27
|
+
if (!flags["agent-id"] && !flags.model) {
|
|
28
|
+
this.error("Either --agent-id or --model is required");
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const client = getClient();
|
|
32
|
+
const data = await client.documentAi.process({
|
|
33
|
+
url: flags.url,
|
|
34
|
+
organizationId: flags["org-id"],
|
|
35
|
+
...(flags["agent-id"] && { agentId: flags["agent-id"] }),
|
|
36
|
+
...(flags.model && { modelName: flags.model }),
|
|
37
|
+
...(flags.instructions && { instructions: flags.instructions }),
|
|
38
|
+
...(flags["board-id"] && { boardId: flags["board-id"] }),
|
|
39
|
+
...(flags.language && { language: flags.language }),
|
|
40
|
+
...(flags["additional-instructions"] && { additionalDocumentInstructions: flags["additional-instructions"] }),
|
|
41
|
+
...(flags["chunk-size"] !== undefined && { chunkSize: flags["chunk-size"] }),
|
|
42
|
+
...(flags["max-concurrent"] !== undefined && { maxConcurrent: flags["max-concurrent"] }),
|
|
43
|
+
...(flags["max-retries"] !== undefined && { maxRetries: flags["max-retries"] }),
|
|
44
|
+
...(flags["enhanced-processing"] !== undefined && { useEnhancedProcessing: flags["enhanced-processing"] }),
|
|
45
|
+
});
|
|
46
|
+
if (flags.json) {
|
|
47
|
+
this.log(JSON.stringify({ ok: true, data }, null, 2));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
this.log(`\n✅ Document processed`);
|
|
51
|
+
this.log(JSON.stringify(data, null, 2));
|
|
52
|
+
this.log("");
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
this.error(`Failed: ${error.message}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class DocumentAiSuggestSchema extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
url: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
"org-id": import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
model: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { getClient } from "../../lib/client.js";
|
|
4
|
+
export default class DocumentAiSuggestSchema extends BaseCommand {
|
|
5
|
+
static description = "Ask the LLM to inspect a sample document and suggest an extraction schema";
|
|
6
|
+
static examples = [
|
|
7
|
+
"imbrace document-ai suggest-schema --url https://example.com/sample.pdf --org-id org_xxx --json",
|
|
8
|
+
"imbrace document-ai suggest-schema --url https://example.com/sample.pdf --org-id org_xxx --model gpt-4o --json",
|
|
9
|
+
];
|
|
10
|
+
static flags = {
|
|
11
|
+
url: Flags.string({ description: "URL of the sample document", required: true }),
|
|
12
|
+
"org-id": Flags.string({ description: "Organization ID", required: true }),
|
|
13
|
+
model: Flags.string({ description: "LLM model to use for inspection" }),
|
|
14
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
15
|
+
};
|
|
16
|
+
async run() {
|
|
17
|
+
const { flags } = await this.parse(DocumentAiSuggestSchema);
|
|
18
|
+
try {
|
|
19
|
+
const client = getClient();
|
|
20
|
+
const data = await client.documentAi.suggestSchema({
|
|
21
|
+
url: flags.url,
|
|
22
|
+
organizationId: flags["org-id"],
|
|
23
|
+
...(flags.model && { modelName: flags.model }),
|
|
24
|
+
});
|
|
25
|
+
if (flags.json) {
|
|
26
|
+
this.log(JSON.stringify({ ok: true, data }, null, 2));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
this.log(`\n✅ Schema suggested`);
|
|
30
|
+
this.log(JSON.stringify(data, null, 2));
|
|
31
|
+
this.log("");
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
this.error(`Failed: ${error.message}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class DocumentAiUpdate extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
instructions: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
model: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
"provider-id": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
schema: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
"schema-file": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
"workflow-name": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
18
|
+
};
|
|
19
|
+
run(): Promise<void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { BaseCommand } from "../../base-command.js";
|
|
4
|
+
import { getClient } from "../../lib/client.js";
|
|
5
|
+
export default class DocumentAiUpdate extends BaseCommand {
|
|
6
|
+
static description = "Update a Document AI agent (partial — pass any subset of flags)";
|
|
7
|
+
static examples = [
|
|
8
|
+
'imbrace document-ai update <agentId> --instructions "Updated rules" --json',
|
|
9
|
+
'imbrace document-ai update <agentId> --schema-file ./new-schema.json',
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
id: Args.string({ description: "Document AI agent ID", required: true }),
|
|
13
|
+
};
|
|
14
|
+
static flags = {
|
|
15
|
+
name: Flags.string({ char: "n", description: "New display name" }),
|
|
16
|
+
instructions: Flags.string({ char: "i", description: "New system prompt" }),
|
|
17
|
+
model: Flags.string({ description: "New LLM model ID" }),
|
|
18
|
+
"provider-id": Flags.string({ description: "New provider UUID" }),
|
|
19
|
+
schema: Flags.string({ description: "New JSON schema (inline)" }),
|
|
20
|
+
"schema-file": Flags.string({ description: "Path to new JSON schema file" }),
|
|
21
|
+
description: Flags.string({ char: "d", description: "New description" }),
|
|
22
|
+
"workflow-name": Flags.string({ description: "New workflow name" }),
|
|
23
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
24
|
+
};
|
|
25
|
+
async run() {
|
|
26
|
+
const { args, flags } = await this.parse(DocumentAiUpdate);
|
|
27
|
+
let schema;
|
|
28
|
+
if (flags.schema) {
|
|
29
|
+
try {
|
|
30
|
+
schema = JSON.parse(flags.schema);
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
this.error(`--schema is not valid JSON: ${e.message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else if (flags["schema-file"]) {
|
|
37
|
+
try {
|
|
38
|
+
schema = JSON.parse(readFileSync(flags["schema-file"], "utf8"));
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
this.error(`--schema-file is not valid JSON: ${e.message}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const body = {};
|
|
45
|
+
if (flags.name)
|
|
46
|
+
body.name = flags.name;
|
|
47
|
+
if (flags.instructions)
|
|
48
|
+
body.instructions = flags.instructions;
|
|
49
|
+
if (flags.model)
|
|
50
|
+
body.model_id = flags.model;
|
|
51
|
+
if (flags["provider-id"])
|
|
52
|
+
body.provider_id = flags["provider-id"];
|
|
53
|
+
if (flags.description)
|
|
54
|
+
body.description = flags.description;
|
|
55
|
+
if (flags["workflow-name"])
|
|
56
|
+
body.workflow_name = flags["workflow-name"];
|
|
57
|
+
if (schema)
|
|
58
|
+
body.schema = schema;
|
|
59
|
+
if (Object.keys(body).length === 0) {
|
|
60
|
+
this.error("Provide at least one field to update. See: imbrace document-ai update -h");
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const client = getClient();
|
|
64
|
+
const data = await client.documentAi.updateAgent(args.id, body);
|
|
65
|
+
const message = "Document AI Agent updated";
|
|
66
|
+
if (flags.json) {
|
|
67
|
+
this.log(JSON.stringify({ ok: true, message, data }, null, 2));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
this.log(`\n✅ ${message}\n`);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
this.error(`Failed: ${error.message}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class GuardrailCreate extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
model: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
instructions: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
"guardrail-provider-id": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
"org-id": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
"unsafe-categories": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
"custom-unsafe-patterns": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
"competitor-keywords": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
"id-only": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
17
|
+
};
|
|
18
|
+
run(): Promise<void>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { input } from "@inquirer/prompts";
|
|
4
|
+
import { getClient } from "../../lib/client.js";
|
|
5
|
+
export default class GuardrailCreate extends BaseCommand {
|
|
6
|
+
static description = "Create a Guardrail (content safety + compliance rules attached to AI agents)";
|
|
7
|
+
static examples = [
|
|
8
|
+
'imbrace guardrail create --name "PII Filter" --instructions "Block any PII (SSN, credit card, email)" --json',
|
|
9
|
+
'imbrace guardrail create --name "Brand Safety" --model model-armor --instructions "Refuse competitor mentions" --competitor-keywords "Competitor1,Competitor2" --json',
|
|
10
|
+
];
|
|
11
|
+
static flags = {
|
|
12
|
+
name: Flags.string({ char: "n", description: "Guardrail name" }),
|
|
13
|
+
model: Flags.string({
|
|
14
|
+
description: "Guardrail model. Default: nim-nemo (NVIDIA NIM). Other supported: 'model-armor' (Google) or a custom guardrail-provider model.",
|
|
15
|
+
}),
|
|
16
|
+
instructions: Flags.string({ char: "i", description: "Safety / compliance rules to enforce" }),
|
|
17
|
+
"guardrail-provider-id": Flags.string({ description: "Guardrail provider UUID (only when using a custom guardrail provider)" }),
|
|
18
|
+
"org-id": Flags.string({ description: "Organization ID. Auto-fetched from account if omitted." }),
|
|
19
|
+
description: Flags.string({ char: "d", description: "Human-readable description" }),
|
|
20
|
+
"unsafe-categories": Flags.string({ description: "Comma-separated unsafe categories (e.g. 'violence,hate,sexual')" }),
|
|
21
|
+
"custom-unsafe-patterns": Flags.string({ description: "Comma-separated custom regex patterns to block (nim-nemo only)" }),
|
|
22
|
+
"competitor-keywords": Flags.string({ description: "Comma-separated competitor names to flag (nim-nemo only)" }),
|
|
23
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
24
|
+
"id-only": Flags.boolean({ description: "Print only the new guardrail ID" }),
|
|
25
|
+
};
|
|
26
|
+
async run() {
|
|
27
|
+
const { flags } = await this.parse(GuardrailCreate);
|
|
28
|
+
const nonInteractive = flags.json || flags["id-only"];
|
|
29
|
+
const name = flags.name ?? (nonInteractive ? this.error("--name is required with --json or --id-only") : await input({ message: "Guardrail name:" }));
|
|
30
|
+
const instructions = flags.instructions ?? (nonInteractive ? this.error("--instructions is required with --json or --id-only") : await input({ message: "Instructions:" }));
|
|
31
|
+
const model = flags.model ?? "nim-nemo";
|
|
32
|
+
const split = (s) => s.split(",").map((x) => x.trim()).filter(Boolean);
|
|
33
|
+
try {
|
|
34
|
+
const client = getClient();
|
|
35
|
+
const orgId = flags["org-id"] || (await client.account.getAccount()).organization_id;
|
|
36
|
+
const isModelArmor = model === "model-armor";
|
|
37
|
+
const data = await client.ai.createGuardrail({
|
|
38
|
+
name,
|
|
39
|
+
model,
|
|
40
|
+
instructions: isModelArmor ? "" : instructions,
|
|
41
|
+
org_id: orgId,
|
|
42
|
+
...(flags.description && { description: flags.description }),
|
|
43
|
+
...(flags["guardrail-provider-id"] && { guardrail_provider_id: flags["guardrail-provider-id"] }),
|
|
44
|
+
...(flags["unsafe-categories"] && { unsafe_categories: split(flags["unsafe-categories"]) }),
|
|
45
|
+
// Patterns + competitor lists only valid for nim-nemo.
|
|
46
|
+
...(!isModelArmor && flags["custom-unsafe-patterns"] && { custom_unsafe_patterns: split(flags["custom-unsafe-patterns"]) }),
|
|
47
|
+
...(!isModelArmor && flags["competitor-keywords"] && { competitor_keywords: split(flags["competitor-keywords"]) }),
|
|
48
|
+
});
|
|
49
|
+
// Backend returns `guardrails_config_id`, not `_id`.
|
|
50
|
+
const id = data?.guardrails_config_id ?? data?._id ?? "";
|
|
51
|
+
if (flags["id-only"]) {
|
|
52
|
+
this.log(id);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const message = `Guardrail "${name}" created`;
|
|
56
|
+
if (flags.json) {
|
|
57
|
+
this.log(JSON.stringify({ ok: true, message, data: { ...data, _id: id } }, null, 2));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
this.log(`\n✅ ${message}`);
|
|
61
|
+
if (id)
|
|
62
|
+
this.log(` ID: ${id}`);
|
|
63
|
+
this.log(`\n Attach via 'imbrace ai-agent create --guardrail-id ${id || "<id>"}'.\n`);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
this.error(`Failed: ${error.message}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class GuardrailDelete extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|