@corvio/cli 0.1.0-beta.15 → 0.1.0-beta.17
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 +4 -0
- package/dist/cli.js +207 -70
- package/dist/core.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,8 @@ corvio agents connect --provider codex --project . --json
|
|
|
10
10
|
corvio collaboration status --json --no-input
|
|
11
11
|
corvio ask --prompt 'Summarize recurring launch risks' --json
|
|
12
12
|
corvio files upload --file ./research.pdf --json
|
|
13
|
+
corvio files organize <asset_id> --instruction 'Create a reusable decision brief' --yes --json
|
|
14
|
+
corvio files operation <operation_id> --json
|
|
13
15
|
corvio sync init --dir ./knowledge --root-node-id <node_id> --json
|
|
14
16
|
corvio update check --json
|
|
15
17
|
```
|
|
@@ -18,6 +20,8 @@ When no environment key is configured, run `corvio auth login`. Login creates on
|
|
|
18
20
|
|
|
19
21
|
The CLI rejects unknown/duplicate options and malformed integer bounds before network access. Normal API calls have a bounded timeout (`CORVIO_REQUEST_TIMEOUT_MS`, maximum ten minutes); only reads, explicit idempotency contracts, revision guards, and other owner-declared safe operations retry automatically. Document updates preflight the current revision when `--expected-revision` is omitted. When the executing principal is a connected Agent, `docs update` also requires `--change-summary`, creates a visible document-level comment after the guarded write, and returns its receipt; a comment failure is reported as a partial effect rather than silent success. When a Corvio document or comment supplied the task, use `corvio agent closeout` to return the verified outcome, optionally resolve the thread, and read both document and thread back. Downloads, uploads, and Markdown pulls verify SHA-256 receipts before replacing local files; local writes are atomic, remote default filenames cannot escape the current directory, and Sync refuses symbolic-link traversal while checkpointing each successful push.
|
|
20
22
|
|
|
23
|
+
File organization is asynchronous. A queued organization receipt is progress, not completion: continue from its stable operation ID with `corvio files operation <operation_id>` and only report completion after the terminal receipt exposes the resulting artifacts, Skill evaluation, and durable links.
|
|
24
|
+
|
|
21
25
|
## Project Agent collaboration
|
|
22
26
|
|
|
23
27
|
Connect the current project with the user credential. User and Agent credentials stay deliberately separate, and the secret is never printed, written into the project, or passed to the provider:
|
package/dist/cli.js
CHANGED
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
agentCredentialPath,
|
|
40
40
|
} from "./core.js";
|
|
41
41
|
|
|
42
|
-
const VERSION = "0.1.0-beta.
|
|
42
|
+
const VERSION = "0.1.0-beta.17";
|
|
43
43
|
const DEFAULT_API_BASE = "https://api.corvio.ai/v1";
|
|
44
44
|
const DEFAULT_APP_BASE = "https://corvio.ai";
|
|
45
45
|
const USER_AGENT = `corvio-cli/${VERSION}`;
|
|
@@ -69,7 +69,11 @@ const COMMAND_OPTIONS = Object.freeze({
|
|
|
69
69
|
"workspaces:create": ["name", "kind", "description", "idempotency-key"],
|
|
70
70
|
"capabilities:": [],
|
|
71
71
|
"collaboration:status": ["project", "provider"],
|
|
72
|
-
"ask:": [
|
|
72
|
+
"ask:": [
|
|
73
|
+
"prompt", "conversation-id", "sources", "allow-actions", "context-file", "idempotency-key",
|
|
74
|
+
"processing-profile", "max-processing-profile", "scan-mode", "skills-extraction-mode", "caller-model",
|
|
75
|
+
"file", "asset-ids", "mime-type",
|
|
76
|
+
],
|
|
73
77
|
"agents:list": ["include-revoked"],
|
|
74
78
|
"agents:connect": [
|
|
75
79
|
"handle", "display-name", "provider", "project", "permission-profile", "trigger-policy",
|
|
@@ -88,7 +92,10 @@ const COMMAND_OPTIONS = Object.freeze({
|
|
|
88
92
|
"agent:reply": ["document-id", "id", "body", "source-event-id", "source-event-lease-token", "start-new-chain", "idempotency-key"],
|
|
89
93
|
"agent:status": ["document-id", "id", "status"],
|
|
90
94
|
"agent:closeout": ["document-id", "thread-id", "body", "status", "idempotency-key"],
|
|
91
|
-
"agent:run": [
|
|
95
|
+
"agent:run": [
|
|
96
|
+
"once", "handler", "provider", "worker-id", "lease-seconds", "wait-seconds", "sources", "project",
|
|
97
|
+
"processing-profile", "max-processing-profile", "scan-mode", "skills-extraction-mode", "caller-model",
|
|
98
|
+
],
|
|
92
99
|
"questions:list": ["limit", "cursor", "conversation-id"],
|
|
93
100
|
"questions:get": ["id"],
|
|
94
101
|
"conversations:list": ["limit", "cursor"],
|
|
@@ -108,8 +115,15 @@ const COMMAND_OPTIONS = Object.freeze({
|
|
|
108
115
|
"files:list": ["limit"],
|
|
109
116
|
"files:get": ["id"],
|
|
110
117
|
"files:download": ["id", "output"],
|
|
111
|
-
"files:upload": [
|
|
112
|
-
|
|
118
|
+
"files:upload": [
|
|
119
|
+
"file", "mime-type", "organize", "instruction", "target-root-node-id", "additional-asset-ids",
|
|
120
|
+
"processing-profile", "max-processing-profile", "scan-mode", "skills-extraction-mode", "caller-model",
|
|
121
|
+
],
|
|
122
|
+
"files:organize": [
|
|
123
|
+
"id", "additional-asset-ids", "instruction", "target-root-node-id",
|
|
124
|
+
"processing-profile", "max-processing-profile", "scan-mode", "skills-extraction-mode", "caller-model",
|
|
125
|
+
],
|
|
126
|
+
"files:operation": ["id"],
|
|
113
127
|
"files:open": ["id"],
|
|
114
128
|
"sync:init": ["root-node-id", "dir", "name", "force"],
|
|
115
129
|
"sync:status": ["dir"],
|
|
@@ -127,7 +141,7 @@ Usage:
|
|
|
127
141
|
corvio workspaces list|use|current|create [id]
|
|
128
142
|
corvio capabilities
|
|
129
143
|
corvio collaboration status [--project <path>] [--provider codex|claude_code|copilot]
|
|
130
|
-
corvio ask --prompt <text> [--conversation-id <id>] [--allow-actions]
|
|
144
|
+
corvio ask --prompt <text> [--file <path>] [--asset-ids <id,id>] [--conversation-id <id>] [--allow-actions] [--processing-profile auto|economy|standard|deep]
|
|
131
145
|
corvio agents list|connect|create|update|rotate [id]
|
|
132
146
|
corvio agent claim|renew|complete|fail|comments|comment|reply|status|closeout|run [id]
|
|
133
147
|
corvio questions list|get [id]
|
|
@@ -135,7 +149,7 @@ Usage:
|
|
|
135
149
|
corvio search <query>
|
|
136
150
|
corvio docs list|get|create|update|move|archive|restore|share|open [id]
|
|
137
151
|
corvio projects list|create
|
|
138
|
-
corvio files list|get|download|upload|organize|open [id]
|
|
152
|
+
corvio files list|get|download|upload|organize|operation|open [id]
|
|
139
153
|
corvio sync init|status|plan|pull|push|resolve
|
|
140
154
|
corvio update check
|
|
141
155
|
|
|
@@ -156,15 +170,15 @@ const COMMAND_HELP = Object.freeze({
|
|
|
156
170
|
workspaces: `Usage:\n corvio workspaces list\n corvio workspaces use <workspace-id>\n corvio workspaces current\n corvio workspaces create --name <name> [--kind personal|team]\n\nWorkspace status and blocked capability reasons are returned with each item.`,
|
|
157
171
|
capabilities: `Usage: corvio capabilities [--json]\n\nShow live API resources, principal scopes, selected Workspace status, and CLI compatibility.`,
|
|
158
172
|
collaboration: `Usage:\n corvio collaboration status [--project <path>] [--provider codex|claude_code|copilot]\n\nVerify that the current project has a bound Corvio Agent, the official collaboration Skill is discoverable at the live contract version, and the inbound listener state is reported separately. This is the foreground work-loop readiness check; a listening process alone is not enough.`,
|
|
159
|
-
ask: `Usage: corvio ask --prompt <text> [--conversation-id <id>] [--sources workspace,web,memory] [--allow-actions] [--context-file <json>] [--idempotency-key <key>]
|
|
173
|
+
ask: `Usage: corvio ask --prompt <text> [--file <path>] [--asset-ids <id,id>] [--conversation-id <id>] [--sources workspace,web,memory] [--allow-actions] [--processing-profile auto|economy|standard|deep] [--max-processing-profile economy|standard|deep] [--scan-mode auto|always|off] [--skills-extraction-mode auto|always|off] [--caller-model <host-model>] [--context-file <json>] [--idempotency-key <key>]\n\n--file retains the selected local file, verifies its hash, and attaches the finalized Asset to this exact question. --asset-ids attaches already-retained Corvio Assets. Skill extraction mode always requires --allow-actions; answer-only questions may use auto or off.`,
|
|
160
174
|
agents: `Usage:\n corvio agents list\n corvio agents connect [--provider codex|claude_code|copilot] [--project <path>] [--permission-profile read_only|workspace_write|danger_full_access] [--trigger-policy owner_only|workspace_members] [--display-name <name>] [--recover-credential] [--no-listen]\n corvio agents create --handle <handle> --display-name <name> [--provider codex|claude_code|copilot|custom] [--permissions read,comment,edit]\n corvio agents update <id> [--display-name <name>] [--status active|paused|revoked] [--permissions <list>]\n corvio agents rotate <id>\n\n'connect' binds the current Git project (or --project path) to one stable personal Agent. Repeating it is idempotent; another project creates another Agent. It reports provider/CLI, listener, and foreground Skill readiness separately; run corvio collaboration status after installing or refreshing the Skill. The default workspace_write profile is limited by the provider's native sandbox. owner_only is the safe trigger default. Secrets and absolute project paths stay local.`,
|
|
161
|
-
agent: `Usage:\n corvio agent claim [--worker-id <id>] [--wait-seconds <0-30>]\n corvio agent renew <event-id> --lease-token <token> [--lease-seconds <30-900>]\n corvio agent complete <event-id> --lease-token <token> [--result-file <json>]\n corvio agent fail <event-id> --lease-token <token> --error <message>\n corvio agent mentions --document-id <id> [--query <name>]\n corvio agent comments --document-id <id>\n corvio agent comment --document-id <id> --body <text> [--selection-file <json>] [--start-new-chain] [--idempotency-key <key>]\n corvio agent reply <thread-id> --document-id <id> --body <text> [--source-event-id <id> --source-event-lease-token <token>|--start-new-chain] [--idempotency-key <key>]\n corvio agent status <thread-id> --document-id <id> --status open|resolved\n corvio agent closeout --document-id <id> [--thread-id <id>] --body <verified-result> [--status open|resolved] [--idempotency-key <key>]\n corvio agent run [--provider codex|claude_code|copilot|custom] [--handler <executable>] [--agent <id>] [--once]\n\nUse mentions before commenting when the target is uncertain; aliases resolve to stable user or Agent IDs and ambiguity fails closed. Use closeout when a Corvio document or comment owned the task: it returns the verified result to that surface and reads document/comments back. Agent-to-Agent comments require either a claimed source event or explicit --start-new-chain. The runner iteratively exchanges origin-scoped evidence with Corvio Query/Writer, then invokes the bound provider inside its local project. Local code changes use the recorded provider permission profile; complex Corvio document changes belong to Query/Writer. Provider children never receive Corvio credentials.`,
|
|
175
|
+
agent: `Usage:\n corvio agent claim [--worker-id <id>] [--wait-seconds <0-30>]\n corvio agent renew <event-id> --lease-token <token> [--lease-seconds <30-900>]\n corvio agent complete <event-id> --lease-token <token> [--result-file <json>]\n corvio agent fail <event-id> --lease-token <token> --error <message>\n corvio agent mentions --document-id <id> [--query <name>]\n corvio agent comments --document-id <id>\n corvio agent comment --document-id <id> --body <text> [--selection-file <json>] [--start-new-chain] [--idempotency-key <key>]\n corvio agent reply <thread-id> --document-id <id> --body <text> [--source-event-id <id> --source-event-lease-token <token>|--start-new-chain] [--idempotency-key <key>]\n corvio agent status <thread-id> --document-id <id> --status open|resolved\n corvio agent closeout --document-id <id> [--thread-id <id>] --body <verified-result> [--status open|resolved] [--idempotency-key <key>]\n corvio agent run [--provider codex|claude_code|copilot|custom] [--handler <executable>] [--agent <id>] [--once] [--processing-profile auto|economy|standard|deep] [--max-processing-profile economy|standard|deep] [--scan-mode auto|always|off] [--skills-extraction-mode auto|always|off] [--caller-model <host-model>]\n\nUse mentions before commenting when the target is uncertain; aliases resolve to stable user or Agent IDs and ambiguity fails closed. Use closeout when a Corvio document or comment owned the task: it returns the verified result to that surface and reads document/comments back. Agent-to-Agent comments require either a claimed source event or explicit --start-new-chain. The runner iteratively exchanges origin-scoped evidence with Corvio Query/Writer, then invokes the bound provider inside its local project. Local code changes use the recorded provider permission profile; complex Corvio document changes belong to Query/Writer. Provider children never receive Corvio credentials.`,
|
|
162
176
|
questions: `Usage:\n corvio questions list [--limit <n>] [--cursor <cursor>] [--conversation-id <id>]\n corvio questions get <question-id>`,
|
|
163
177
|
conversations: `Usage:\n corvio conversations list [--limit <n>] [--cursor <cursor>]\n corvio conversations get <conversation-id>`,
|
|
164
178
|
search: `Usage: corvio search <query> [--limit <n>] [--page-id <id>] [--node-id <id>]`,
|
|
165
179
|
docs: `Usage:\n corvio docs list [--limit <n>] [--cursor <cursor>] [--lifecycle active|archived]\n corvio docs get <id> [--output <path>]\n corvio docs create --title <title> [--file <path>|--markdown <text>] [--parent-node-id <id>] [--idempotency-key <key>]\n corvio docs update <id> [--title <title>] [--file <path>|--markdown <text>] [--expected-revision <n>] [--change-summary <text>]\n corvio docs move <id> --parent-node-id <id>\n corvio docs archive <id> --yes\n corvio docs restore <id> --yes\n corvio docs share <id> --yes [--display-name <name>]\n corvio docs open <id>\n\nDirect document commands operate on canonical Page/Markdown. Use \`corvio ask --allow-actions\` for Spreadsheet, Presentation, Code, HTML Artifact, or semantic organization. Agent-authenticated document updates require --change-summary and create a visible document-level comment after the guarded update. When a document/comment is the task owner, use \`corvio agent closeout\` to return verified work to that same collaboration surface and read it back.`,
|
|
166
180
|
projects: `Usage:\n corvio projects list [--limit <n>]\n corvio projects create --title <title> [--idempotency-key <key>]\n\nProjects are durable grouping owners in the Corvio Docs tree. Reuse a matching Project instead of creating one ceremonial Project per file. 'corvio folders' is an alias.`,
|
|
167
|
-
files: `Usage:\n corvio files list [--limit <n>]\n corvio files get <id>\n corvio files download <id> [--output <path>]\n corvio files upload --file <path> [--mime-type <type>]\n corvio files organize <id> --instruction <text> --yes [--
|
|
181
|
+
files: `Usage:\n corvio files list [--limit <n>]\n corvio files get <id>\n corvio files download <id> [--output <path>]\n corvio files upload --file <path> [--mime-type <type>] [--organize --instruction <text> --additional-asset-ids <id,id> --yes]\n corvio files organize <id> --instruction <text> --yes [--additional-asset-ids <id,id>] [--processing-profile auto|economy|standard|deep] [--scan-mode auto|always|off] [--skills-extraction-mode auto|always|off]\n corvio files operation <operation-id>\n corvio files open <id>\n\nUpload alone preserves the original file. Organization is asynchronous: use 'files operation' to read its terminal result, derived artifacts, Skill evaluation, and links before claiming completion.`,
|
|
168
182
|
sync: `Usage:\n corvio sync init --root-node-id <id> [--dir <path>] [--name <name>]\n corvio sync status|plan|pull [--dir <path>]\n corvio sync push --yes [--dir <path>]\n corvio sync resolve --conflict-id <id> --strategy use-remote|keep-local --yes [--dir <path>]`,
|
|
169
183
|
update: `Usage: corvio update check [--json]\n\nCompare this executable with the reviewed API policy and the npm beta dist-tag.`,
|
|
170
184
|
});
|
|
@@ -225,6 +239,7 @@ function validateInvocation(options, positionals) {
|
|
|
225
239
|
"files:get",
|
|
226
240
|
"files:download",
|
|
227
241
|
"files:organize",
|
|
242
|
+
"files:operation",
|
|
228
243
|
"files:open",
|
|
229
244
|
"agents:update",
|
|
230
245
|
"agents:rotate",
|
|
@@ -883,18 +898,61 @@ async function ask(options, positionals) {
|
|
|
883
898
|
const context = options["context-file"]
|
|
884
899
|
? await readJsonObject(options["context-file"], "--context-file")
|
|
885
900
|
: null;
|
|
886
|
-
const
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
901
|
+
const processingProfile = enumOption(options, "processing-profile", ["auto", "economy", "standard", "deep"], "auto");
|
|
902
|
+
const maxProcessingProfile = optionalEnumOption(options, "max-processing-profile", ["economy", "standard", "deep"]);
|
|
903
|
+
const scanMode = enumOption(options, "scan-mode", ["auto", "always", "off"], "auto");
|
|
904
|
+
const skillsExtractionMode = enumOption(options, "skills-extraction-mode", ["auto", "always", "off"], "auto");
|
|
905
|
+
if (skillsExtractionMode === "always" && !options["allow-actions"]) {
|
|
906
|
+
throw new CliError("--skills-extraction-mode always requires --allow-actions.", {
|
|
907
|
+
code: "skills_extraction_requires_actions",
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
const attachedAssets = [];
|
|
911
|
+
if (options.file) {
|
|
912
|
+
attachedAssets.push(await uploadWorkspaceFile(api, options.file, options["mime-type"]));
|
|
913
|
+
}
|
|
914
|
+
const assetIds = listOption(options, "asset-ids", []);
|
|
915
|
+
for (const asset of attachedAssets) assetIds.push(String(asset.id));
|
|
916
|
+
const uniqueAssetIds = [...new Set(assetIds.map((value) => String(value).trim()).filter(Boolean))];
|
|
917
|
+
let result;
|
|
918
|
+
try {
|
|
919
|
+
result = await api.request("/questions", {
|
|
920
|
+
method: "POST",
|
|
921
|
+
headers: {
|
|
922
|
+
"idempotency-key": idempotencyKey(options),
|
|
923
|
+
...(options["caller-model"] ? { "x-corvio-caller-model": String(options["caller-model"]) } : {}),
|
|
924
|
+
},
|
|
925
|
+
body: {
|
|
926
|
+
prompt,
|
|
927
|
+
conversation_id: options["conversation-id"] || null,
|
|
928
|
+
asset_ids: uniqueAssetIds,
|
|
929
|
+
mode: options["allow-actions"] ? "allow_actions" : "answer_only",
|
|
930
|
+
sources: listOption(options, "sources", ["workspace", "web", "memory"]),
|
|
931
|
+
processing_profile: processingProfile,
|
|
932
|
+
max_processing_profile: maxProcessingProfile,
|
|
933
|
+
scan_mode: scanMode,
|
|
934
|
+
skills_extraction_mode: skillsExtractionMode,
|
|
935
|
+
context,
|
|
936
|
+
},
|
|
937
|
+
timeoutMs: 330_000,
|
|
938
|
+
});
|
|
939
|
+
} catch (error) {
|
|
940
|
+
if (attachedAssets.length > 0) {
|
|
941
|
+
throw new CliError(
|
|
942
|
+
`The selected file was retained as Corvio Asset ${attachedAssets[0].id}, but the question did not complete. Retry with --asset-ids ${attachedAssets.map((asset) => asset.id).join(",")}.`,
|
|
943
|
+
{
|
|
944
|
+
code: "question_failed_after_file_retention",
|
|
945
|
+
exitCode: error instanceof CliError ? error.exitCode : EXIT.REMOTE,
|
|
946
|
+
status: error instanceof CliError ? error.status : null,
|
|
947
|
+
details: {
|
|
948
|
+
asset_ids: attachedAssets.map((asset) => asset.id),
|
|
949
|
+
cause: error instanceof Error ? error.message : String(error),
|
|
950
|
+
},
|
|
951
|
+
},
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
throw error;
|
|
955
|
+
}
|
|
898
956
|
const conversationId = String(result?.conversation_id || result?.data?.conversation_id || "").trim();
|
|
899
957
|
if (conversationId && execution.selection?.workspaceId) {
|
|
900
958
|
await storeConversationRoutingReceipt({
|
|
@@ -904,7 +962,29 @@ async function ask(options, positionals) {
|
|
|
904
962
|
apiBase: baseUrl(options),
|
|
905
963
|
});
|
|
906
964
|
}
|
|
907
|
-
writeResult(
|
|
965
|
+
writeResult(
|
|
966
|
+
{
|
|
967
|
+
...result,
|
|
968
|
+
...(attachedAssets.length > 0 ? { attached_assets: attachedAssets } : {}),
|
|
969
|
+
routing: execution.routing,
|
|
970
|
+
},
|
|
971
|
+
{ json: options.json },
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
function enumOption(options, name, allowed, fallback) {
|
|
976
|
+
const value = String(options[name] ?? fallback).trim().toLowerCase();
|
|
977
|
+
if (!allowed.includes(value)) {
|
|
978
|
+
throw new CliError(`--${name} must be one of: ${allowed.join(", ")}.`, {
|
|
979
|
+
code: `${name.replaceAll("-", "_")}_invalid`,
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
return value;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
function optionalEnumOption(options, name, allowed) {
|
|
986
|
+
if (options[name] === undefined) return null;
|
|
987
|
+
return enumOption(options, name, allowed, null);
|
|
908
988
|
}
|
|
909
989
|
|
|
910
990
|
function providerChildEnvironment(extra = {}) {
|
|
@@ -1815,6 +1895,11 @@ async function requestAgentCorvioQuestion(workspaceApi, event, leaseToken, {
|
|
|
1815
1895
|
round,
|
|
1816
1896
|
conversationId = null,
|
|
1817
1897
|
priorTurn = null,
|
|
1898
|
+
processingProfile = "auto",
|
|
1899
|
+
maxProcessingProfile = null,
|
|
1900
|
+
scanMode = "auto",
|
|
1901
|
+
skillsExtractionMode = "auto",
|
|
1902
|
+
callerModel = null,
|
|
1818
1903
|
}) {
|
|
1819
1904
|
const question = await workspaceApi.request("/questions", {
|
|
1820
1905
|
method: "POST",
|
|
@@ -1824,12 +1909,17 @@ async function requestAgentCorvioQuestion(workspaceApi, event, leaseToken, {
|
|
|
1824
1909
|
: `agent-event:${event.id}:query:${round}`,
|
|
1825
1910
|
"x-corvio-agent-event-id": event.id,
|
|
1826
1911
|
"x-corvio-agent-event-lease-token": leaseToken,
|
|
1912
|
+
...(callerModel ? { "x-corvio-caller-model": callerModel } : {}),
|
|
1827
1913
|
},
|
|
1828
1914
|
body: {
|
|
1829
1915
|
prompt: instruction,
|
|
1830
1916
|
...(conversationId ? { conversation_id: conversationId } : {}),
|
|
1831
1917
|
mode,
|
|
1832
1918
|
sources: [],
|
|
1919
|
+
processing_profile: processingProfile,
|
|
1920
|
+
max_processing_profile: maxProcessingProfile,
|
|
1921
|
+
scan_mode: scanMode,
|
|
1922
|
+
skills_extraction_mode: skillsExtractionMode,
|
|
1833
1923
|
context: {
|
|
1834
1924
|
agent_event: agentEventContext(event),
|
|
1835
1925
|
collaboration: event.context,
|
|
@@ -1961,11 +2051,24 @@ async function processClaimedAgentEvent(api, event, options) {
|
|
|
1961
2051
|
const decision = options.handler
|
|
1962
2052
|
? { execution_target: "corvio_document", ...(await runAgentHandler(options.handler, event)) }
|
|
1963
2053
|
: await runProjectProviderPlan(event, provider, binding);
|
|
2054
|
+
const questionExecution = {
|
|
2055
|
+
processingProfile: enumOption(options, "processing-profile", ["auto", "economy", "standard", "deep"], "auto"),
|
|
2056
|
+
maxProcessingProfile: optionalEnumOption(options, "max-processing-profile", ["economy", "standard", "deep"]),
|
|
2057
|
+
scanMode: enumOption(options, "scan-mode", ["auto", "always", "off"], "auto"),
|
|
2058
|
+
skillsExtractionMode: enumOption(options, "skills-extraction-mode", ["auto", "always", "off"], "auto"),
|
|
2059
|
+
callerModel: String(options["caller-model"] || "").trim() || null,
|
|
2060
|
+
};
|
|
2061
|
+
const initialQuestionMode =
|
|
2062
|
+
decision.execution_target === "corvio_document" ||
|
|
2063
|
+
questionExecution.skillsExtractionMode === "always"
|
|
2064
|
+
? "allow_actions"
|
|
2065
|
+
: "answer_only";
|
|
1964
2066
|
const workspaceApi = await agentClient(options, String(event.workspace_id || ""));
|
|
1965
2067
|
let question = await requestAgentCorvioQuestion(workspaceApi, event, leaseToken, {
|
|
1966
2068
|
instruction: decision.instruction,
|
|
1967
|
-
mode:
|
|
2069
|
+
mode: initialQuestionMode,
|
|
1968
2070
|
round: 1,
|
|
2071
|
+
...questionExecution,
|
|
1969
2072
|
});
|
|
1970
2073
|
const questions = [question];
|
|
1971
2074
|
const instructions = new Set([decision.instruction.trim().toLowerCase()]);
|
|
@@ -1990,7 +2093,7 @@ async function processClaimedAgentEvent(api, event, options) {
|
|
|
1990
2093
|
round: 1,
|
|
1991
2094
|
question_id: question.id || null,
|
|
1992
2095
|
conversation_id: question.conversation_id || null,
|
|
1993
|
-
requested_mode:
|
|
2096
|
+
requested_mode: initialQuestionMode,
|
|
1994
2097
|
provider_outcome: providerExecution.outcome,
|
|
1995
2098
|
next_action: providerExecution.next_action,
|
|
1996
2099
|
}];
|
|
@@ -2026,13 +2129,17 @@ async function processClaimedAgentEvent(api, event, options) {
|
|
|
2026
2129
|
break;
|
|
2027
2130
|
}
|
|
2028
2131
|
instructions.add(normalizedInstruction);
|
|
2029
|
-
const requestedMode =
|
|
2132
|
+
const requestedMode =
|
|
2133
|
+
questionExecution.skillsExtractionMode === "always"
|
|
2134
|
+
? "allow_actions"
|
|
2135
|
+
: providerExecution.corvio_mode;
|
|
2030
2136
|
question = await requestAgentCorvioQuestion(workspaceApi, event, leaseToken, {
|
|
2031
2137
|
instruction: nextInstruction,
|
|
2032
2138
|
mode: requestedMode,
|
|
2033
2139
|
round: questions.length + 1,
|
|
2034
2140
|
conversationId: question.conversation_id || null,
|
|
2035
2141
|
priorTurn: providerExecution,
|
|
2142
|
+
...questionExecution,
|
|
2036
2143
|
});
|
|
2037
2144
|
questions.push(question);
|
|
2038
2145
|
providerExecution = await runProjectProviderExecution(
|
|
@@ -2767,6 +2874,51 @@ function mimeTypeFor(path) {
|
|
|
2767
2874
|
})[extension] || "application/octet-stream";
|
|
2768
2875
|
}
|
|
2769
2876
|
|
|
2877
|
+
async function uploadWorkspaceFile(api, inputPath, mimeTypeOverride) {
|
|
2878
|
+
const input = resolve(String(inputPath));
|
|
2879
|
+
const info = await stat(input);
|
|
2880
|
+
if (!info.isFile()) throw new CliError("--file must point to a regular file.", { code: "upload_file_invalid" });
|
|
2881
|
+
if (info.size < 1 || info.size > MAX_UPLOAD_BYTES) {
|
|
2882
|
+
throw new CliError(`--file must be between 1 byte and ${MAX_UPLOAD_BYTES} bytes.`, {
|
|
2883
|
+
code: "upload_file_size_invalid",
|
|
2884
|
+
});
|
|
2885
|
+
}
|
|
2886
|
+
const bytes = await readFile(input);
|
|
2887
|
+
if (bytes.length < 1 || bytes.length > MAX_UPLOAD_BYTES) {
|
|
2888
|
+
throw new CliError(`--file must be between 1 byte and ${MAX_UPLOAD_BYTES} bytes.`, {
|
|
2889
|
+
code: "upload_file_size_invalid",
|
|
2890
|
+
});
|
|
2891
|
+
}
|
|
2892
|
+
const fileName = basename(input);
|
|
2893
|
+
const mimeType = String(mimeTypeOverride || mimeTypeFor(input));
|
|
2894
|
+
const initialized = await api.request("/files/uploads", {
|
|
2895
|
+
method: "POST",
|
|
2896
|
+
body: { file_name: fileName, mime_type: mimeType, size_bytes: bytes.length },
|
|
2897
|
+
});
|
|
2898
|
+
await api.putUrl(initialized.upload_url, bytes, {
|
|
2899
|
+
headers: initialized.upload_headers || {},
|
|
2900
|
+
timeoutMs: 5 * 60_000,
|
|
2901
|
+
});
|
|
2902
|
+
const result = await api.request("/files/uploads:finalize", {
|
|
2903
|
+
method: "POST",
|
|
2904
|
+
retrySafe: true,
|
|
2905
|
+
body: {
|
|
2906
|
+
upload_id: initialized.upload_id,
|
|
2907
|
+
blob_name: initialized.blob_name,
|
|
2908
|
+
file_name: fileName,
|
|
2909
|
+
mime_type: mimeType,
|
|
2910
|
+
size_bytes: bytes.length,
|
|
2911
|
+
},
|
|
2912
|
+
});
|
|
2913
|
+
if (result.content_sha256 && result.content_sha256 !== sha256(bytes)) {
|
|
2914
|
+
throw new CliError("Uploaded file content did not match Corvio's SHA-256 receipt.", {
|
|
2915
|
+
code: "upload_integrity_mismatch",
|
|
2916
|
+
exitCode: EXIT.REMOTE,
|
|
2917
|
+
});
|
|
2918
|
+
}
|
|
2919
|
+
return result;
|
|
2920
|
+
}
|
|
2921
|
+
|
|
2770
2922
|
async function files(options, action, id) {
|
|
2771
2923
|
const { api } = await executionClient(options);
|
|
2772
2924
|
const assetId = id || options.id;
|
|
@@ -2789,66 +2941,51 @@ async function files(options, action, id) {
|
|
|
2789
2941
|
const written = await writeBinaryFile(output, bytes);
|
|
2790
2942
|
result = { ...metadata, output: written };
|
|
2791
2943
|
} else if (action === "upload") {
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
code: "upload_file_size_invalid",
|
|
2804
|
-
});
|
|
2805
|
-
}
|
|
2806
|
-
const fileName = basename(input);
|
|
2807
|
-
const mimeType = String(options["mime-type"] || mimeTypeFor(input));
|
|
2808
|
-
const initialized = await api.request("/files/uploads", {
|
|
2809
|
-
method: "POST",
|
|
2810
|
-
body: { file_name: fileName, mime_type: mimeType, size_bytes: bytes.length },
|
|
2811
|
-
});
|
|
2812
|
-
await api.putUrl(initialized.upload_url, bytes, {
|
|
2813
|
-
headers: initialized.upload_headers || {},
|
|
2814
|
-
timeoutMs: 5 * 60_000,
|
|
2815
|
-
});
|
|
2816
|
-
result = await api.request("/files/uploads:finalize", {
|
|
2817
|
-
method: "POST",
|
|
2818
|
-
retrySafe: true,
|
|
2819
|
-
body: {
|
|
2820
|
-
upload_id: initialized.upload_id,
|
|
2821
|
-
blob_name: initialized.blob_name,
|
|
2822
|
-
file_name: fileName,
|
|
2823
|
-
mime_type: mimeType,
|
|
2824
|
-
size_bytes: bytes.length,
|
|
2825
|
-
},
|
|
2826
|
-
});
|
|
2827
|
-
if (result.content_sha256 && result.content_sha256 !== sha256(bytes)) {
|
|
2828
|
-
throw new CliError("Uploaded file content did not match Corvio's SHA-256 receipt.", {
|
|
2829
|
-
code: "upload_integrity_mismatch",
|
|
2830
|
-
exitCode: EXIT.REMOTE,
|
|
2944
|
+
result = await uploadWorkspaceFile(
|
|
2945
|
+
api,
|
|
2946
|
+
option(options, "file", { required: true }),
|
|
2947
|
+
options["mime-type"],
|
|
2948
|
+
);
|
|
2949
|
+
if (options.organize) {
|
|
2950
|
+
requireConfirmation(options, "Starting semantic organization for the uploaded file");
|
|
2951
|
+
const organization = await api.request(`/files/${resourcePath(result.id)}:organize`, {
|
|
2952
|
+
method: "POST",
|
|
2953
|
+
headers: options["caller-model"] ? { "x-corvio-caller-model": String(options["caller-model"]) } : {},
|
|
2954
|
+
body: fileOrganizationBody(options),
|
|
2831
2955
|
});
|
|
2956
|
+
result = { file: result, organization };
|
|
2832
2957
|
}
|
|
2833
2958
|
} else if (action === "organize") {
|
|
2834
2959
|
requireConfirmation(options, "Starting a file organization run");
|
|
2835
2960
|
result = await api.request(`/files/${resourcePath(assetId || option(options, "id", { required: true }))}:organize`, {
|
|
2836
2961
|
method: "POST",
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
target_root_node_id: options["target-root-node-id"] || null,
|
|
2840
|
-
},
|
|
2962
|
+
headers: options["caller-model"] ? { "x-corvio-caller-model": String(options["caller-model"]) } : {},
|
|
2963
|
+
body: fileOrganizationBody(options),
|
|
2841
2964
|
});
|
|
2965
|
+
} else if (action === "operation") {
|
|
2966
|
+
result = await api.request(`/file-operations/${resourcePath(assetId || option(options, "id", { required: true }))}`);
|
|
2842
2967
|
} else if (action === "open") {
|
|
2843
2968
|
const targetId = assetId || option(options, "id", { required: true });
|
|
2844
2969
|
const target = `${String(process.env.CORVIO_APP_BASE || DEFAULT_APP_BASE).replace(/\/+$/, "")}/app/a/${resourcePath(targetId)}`;
|
|
2845
2970
|
result = { file_id: targetId, url: target, opened: options["no-input"] ? false : await openBrowser(target) };
|
|
2846
2971
|
} else {
|
|
2847
|
-
throw new CliError("files action must be list, get, download, upload, organize, or open.");
|
|
2972
|
+
throw new CliError("files action must be list, get, download, upload, organize, operation, or open.");
|
|
2848
2973
|
}
|
|
2849
2974
|
writeResult(result, { json: options.json });
|
|
2850
2975
|
}
|
|
2851
2976
|
|
|
2977
|
+
function fileOrganizationBody(options) {
|
|
2978
|
+
return {
|
|
2979
|
+
instruction: option(options, "instruction", { required: true }),
|
|
2980
|
+
target_root_node_id: options["target-root-node-id"] || null,
|
|
2981
|
+
additional_asset_ids: listOption(options, "additional-asset-ids", []),
|
|
2982
|
+
processing_profile: enumOption(options, "processing-profile", ["auto", "economy", "standard", "deep"], "auto"),
|
|
2983
|
+
max_processing_profile: optionalEnumOption(options, "max-processing-profile", ["economy", "standard", "deep"]),
|
|
2984
|
+
scan_mode: enumOption(options, "scan-mode", ["auto", "always", "off"], "auto"),
|
|
2985
|
+
skills_extraction_mode: enumOption(options, "skills-extraction-mode", ["auto", "always", "off"], "auto"),
|
|
2986
|
+
};
|
|
2987
|
+
}
|
|
2988
|
+
|
|
2852
2989
|
function sha256(content) {
|
|
2853
2990
|
return createHash("sha256").update(content).digest("hex");
|
|
2854
2991
|
}
|
package/dist/core.js
CHANGED