dexto 1.14.5 → 2.0.0-beta.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/cli/auth/billing.d.ts +0 -6
- package/dist/cli/auth/billing.d.ts.map +1 -1
- package/dist/cli/auth/billing.js +0 -23
- package/dist/cli/auth/constants.d.ts +3 -31
- package/dist/cli/auth/constants.d.ts.map +1 -1
- package/dist/cli/auth/constants.js +9 -33
- package/dist/cli/auth/index.d.ts +2 -9
- package/dist/cli/auth/index.d.ts.map +1 -1
- package/dist/cli/auth/index.js +2 -7
- package/dist/cli/auth/sign-in-runtime.d.ts +12 -0
- package/dist/cli/auth/sign-in-runtime.d.ts.map +1 -0
- package/dist/cli/auth/sign-in-runtime.js +59 -0
- package/dist/cli/cloud/app-scopes.d.ts +4 -0
- package/dist/cli/cloud/app-scopes.d.ts.map +1 -0
- package/dist/cli/cloud/app-scopes.js +19 -0
- package/dist/cli/cloud/command.d.ts +143 -0
- package/dist/cli/cloud/command.d.ts.map +1 -0
- package/dist/cli/cloud/command.js +202 -0
- package/dist/cli/cloud/commands/account.d.ts +11 -0
- package/dist/cli/cloud/commands/account.d.ts.map +1 -0
- package/dist/cli/cloud/commands/account.js +128 -0
- package/dist/cli/cloud/commands/agents.d.ts +3 -0
- package/dist/cli/cloud/commands/agents.d.ts.map +1 -0
- package/dist/cli/cloud/commands/agents.js +524 -0
- package/dist/cli/cloud/commands/api.d.ts +3 -0
- package/dist/cli/cloud/commands/api.d.ts.map +1 -0
- package/dist/cli/cloud/commands/api.js +26 -0
- package/dist/cli/cloud/commands/app-files.d.ts +29 -0
- package/dist/cli/cloud/commands/app-files.d.ts.map +1 -0
- package/dist/cli/cloud/commands/app-files.js +72 -0
- package/dist/cli/cloud/commands/automations.d.ts +3 -0
- package/dist/cli/cloud/commands/automations.d.ts.map +1 -0
- package/dist/cli/cloud/commands/automations.js +232 -0
- package/dist/cli/cloud/commands/chats.d.ts +3 -0
- package/dist/cli/cloud/commands/chats.d.ts.map +1 -0
- package/dist/cli/cloud/commands/chats.js +189 -0
- package/dist/cli/cloud/commands/data-deletions.d.ts +3 -0
- package/dist/cli/cloud/commands/data-deletions.d.ts.map +1 -0
- package/dist/cli/cloud/commands/data-deletions.js +54 -0
- package/dist/cli/cloud/commands/deploys.d.ts +10 -0
- package/dist/cli/cloud/commands/deploys.d.ts.map +1 -0
- package/dist/cli/cloud/commands/deploys.js +223 -0
- package/dist/cli/cloud/commands/drive.d.ts +12 -0
- package/dist/cli/cloud/commands/drive.d.ts.map +1 -0
- package/dist/cli/cloud/commands/drive.js +320 -0
- package/dist/cli/cloud/commands/files.d.ts +24 -0
- package/dist/cli/cloud/commands/files.d.ts.map +1 -0
- package/dist/cli/cloud/commands/files.js +282 -0
- package/dist/cli/cloud/commands/find.d.ts +3 -0
- package/dist/cli/cloud/commands/find.d.ts.map +1 -0
- package/dist/cli/cloud/commands/find.js +63 -0
- package/dist/cli/cloud/commands/models.d.ts +3 -0
- package/dist/cli/cloud/commands/models.d.ts.map +1 -0
- package/dist/cli/cloud/commands/models.js +248 -0
- package/dist/cli/cloud/commands/profile.d.ts +3 -0
- package/dist/cli/cloud/commands/profile.d.ts.map +1 -0
- package/dist/cli/cloud/commands/profile.js +119 -0
- package/dist/cli/cloud/commands/projects.d.ts +5 -0
- package/dist/cli/cloud/commands/projects.d.ts.map +1 -0
- package/dist/cli/cloud/commands/projects.js +66 -0
- package/dist/cli/cloud/commands/publish.d.ts +3 -0
- package/dist/cli/cloud/commands/publish.d.ts.map +1 -0
- package/dist/cli/cloud/commands/publish.js +138 -0
- package/dist/cli/cloud/commands/sandboxes.d.ts +3 -0
- package/dist/cli/cloud/commands/sandboxes.d.ts.map +1 -0
- package/dist/cli/cloud/commands/sandboxes.js +265 -0
- package/dist/cli/cloud/commands/secrets.d.ts +3 -0
- package/dist/cli/cloud/commands/secrets.d.ts.map +1 -0
- package/dist/cli/cloud/commands/secrets.js +110 -0
- package/dist/cli/cloud/commands/skills.d.ts +3 -0
- package/dist/cli/cloud/commands/skills.d.ts.map +1 -0
- package/dist/cli/cloud/commands/skills.js +202 -0
- package/dist/cli/cloud/commands/web.d.ts +3 -0
- package/dist/cli/cloud/commands/web.d.ts.map +1 -0
- package/dist/cli/cloud/commands/web.js +53 -0
- package/dist/cli/cloud/commands/workspace-apps.d.ts +58 -0
- package/dist/cli/cloud/commands/workspace-apps.d.ts.map +1 -0
- package/dist/cli/cloud/commands/workspace-apps.js +656 -0
- package/dist/cli/cloud/commands/workspace.d.ts +36 -0
- package/dist/cli/cloud/commands/workspace.d.ts.map +1 -0
- package/dist/cli/cloud/commands/workspace.js +279 -0
- package/dist/cli/cloud/connection.d.ts +33 -0
- package/dist/cli/cloud/connection.d.ts.map +1 -0
- package/dist/cli/cloud/connection.js +38 -0
- package/dist/cli/cloud/events.d.ts +63 -0
- package/dist/cli/cloud/events.d.ts.map +1 -0
- package/dist/cli/cloud/events.js +72 -0
- package/dist/cli/cloud/host.d.ts +9 -0
- package/dist/cli/cloud/host.d.ts.map +1 -0
- package/dist/cli/cloud/host.js +105 -0
- package/dist/cli/cloud/local-chats.d.ts +73 -0
- package/dist/cli/cloud/local-chats.d.ts.map +1 -0
- package/dist/cli/cloud/local-chats.js +441 -0
- package/dist/cli/cloud/output.d.ts +34 -0
- package/dist/cli/cloud/output.d.ts.map +1 -0
- package/dist/cli/cloud/output.js +76 -0
- package/dist/cli/cloud/run.d.ts +26 -0
- package/dist/cli/cloud/run.d.ts.map +1 -0
- package/dist/cli/cloud/run.js +444 -0
- package/dist/cli/cloud/runtime.d.ts +33 -0
- package/dist/cli/cloud/runtime.d.ts.map +1 -0
- package/dist/cli/cloud/runtime.js +86 -0
- package/dist/cli/cloud/tar.d.ts +9 -0
- package/dist/cli/cloud/tar.d.ts.map +1 -0
- package/dist/cli/cloud/tar.js +69 -0
- package/dist/cli/cloud/transfer.d.ts +13 -0
- package/dist/cli/cloud/transfer.d.ts.map +1 -0
- package/dist/cli/cloud/transfer.js +35 -0
- package/dist/cli/cloud/v1.d.ts +19 -0
- package/dist/cli/cloud/v1.d.ts.map +1 -0
- package/dist/cli/cloud/v1.js +65 -0
- package/dist/cli/cloud/zip.d.ts +8 -0
- package/dist/cli/cloud/zip.d.ts.map +1 -0
- package/dist/cli/cloud/zip.js +66 -0
- package/dist/cli/commands/auth/sign-in-commands.d.ts +62 -0
- package/dist/cli/commands/auth/sign-in-commands.d.ts.map +1 -0
- package/dist/cli/commands/auth/sign-in-commands.js +247 -0
- package/dist/cli/commands/auth/sign-in-context.d.ts +16 -0
- package/dist/cli/commands/auth/sign-in-context.d.ts.map +1 -0
- package/dist/cli/commands/auth/sign-in-context.js +68 -0
- package/dist/cli/commands/cloud/register.d.ts +5 -0
- package/dist/cli/commands/cloud/register.d.ts.map +1 -1
- package/dist/cli/commands/cloud/register.js +42 -24
- package/dist/cli/commands/create-app.js +5 -6
- package/dist/cli/commands/create-image.d.ts.map +1 -1
- package/dist/cli/commands/create-image.js +9 -10
- package/dist/cli/commands/index.d.ts +0 -2
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +0 -2
- package/dist/cli/commands/init.d.ts +0 -2
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +5 -26
- package/dist/cli/commands/run/headless.js +2 -2
- package/dist/cli/commands/run/output.d.ts +29 -10
- package/dist/cli/commands/run/output.d.ts.map +1 -1
- package/dist/cli/commands/run/output.js +44 -22
- package/dist/cli/commands/run/register.d.ts.map +1 -1
- package/dist/cli/commands/run/register.js +21 -9
- package/dist/cli/commands/session/register.d.ts.map +1 -1
- package/dist/cli/commands/session/register.js +51 -21
- package/dist/cli/commands/session-commands.js +1 -1
- package/dist/cli/commands/setup.js +17 -14
- package/dist/cli/help-json.d.ts +22 -0
- package/dist/cli/help-json.d.ts.map +1 -0
- package/dist/cli/help-json.js +20 -0
- package/dist/cli/modes/cli.d.ts.map +1 -1
- package/dist/cli/modes/cli.js +42 -9
- package/dist/cli/modes/server.js +8 -8
- package/dist/cli/modes/web.js +3 -3
- package/dist/cli/utils/dexto-auth-check.d.ts +1 -1
- package/dist/cli/utils/dexto-auth-check.d.ts.map +1 -1
- package/dist/cli/utils/dexto-auth-check.js +4 -5
- package/dist/cli/utils/dexto-setup.d.ts +4 -5
- package/dist/cli/utils/dexto-setup.d.ts.map +1 -1
- package/dist/cli/utils/dexto-setup.js +17 -14
- package/dist/cli/utils/provider-setup.js +1 -1
- package/dist/cli/utils/scaffolding-utils.d.ts +9 -3
- package/dist/cli/utils/scaffolding-utils.d.ts.map +1 -1
- package/dist/cli/utils/scaffolding-utils.js +48 -40
- package/dist/cli/utils/version-check.d.ts.map +1 -1
- package/dist/cli/utils/version-check.js +2 -1
- package/dist/index-main.js +33 -65
- package/dist/webui/assets/index-D9xiOs62.js +1649 -0
- package/dist/webui/index.html +1 -1
- package/package.json +15 -14
- package/dist/cli/auth/api-client.d.ts +0 -125
- package/dist/cli/auth/api-client.d.ts.map +0 -1
- package/dist/cli/auth/api-client.js +0 -585
- package/dist/cli/auth/device.d.ts +0 -14
- package/dist/cli/auth/device.d.ts.map +0 -1
- package/dist/cli/auth/device.js +0 -84
- package/dist/cli/auth/dexto-api-key.d.ts +0 -34
- package/dist/cli/auth/dexto-api-key.d.ts.map +0 -1
- package/dist/cli/auth/dexto-api-key.js +0 -160
- package/dist/cli/auth/login-persistence.d.ts +0 -15
- package/dist/cli/auth/login-persistence.d.ts.map +0 -1
- package/dist/cli/auth/login-persistence.js +0 -72
- package/dist/cli/auth/oauth.d.ts +0 -39
- package/dist/cli/auth/oauth.d.ts.map +0 -1
- package/dist/cli/auth/oauth.js +0 -434
- package/dist/cli/auth/service.d.ts +0 -24
- package/dist/cli/auth/service.d.ts.map +0 -1
- package/dist/cli/auth/service.js +0 -161
- package/dist/cli/auth/types.d.ts +0 -11
- package/dist/cli/auth/types.d.ts.map +0 -1
- package/dist/cli/auth/types.js +0 -1
- package/dist/cli/cloud-chat.d.ts +0 -18
- package/dist/cli/cloud-chat.d.ts.map +0 -1
- package/dist/cli/cloud-chat.js +0 -734
- package/dist/cli/commands/auth/index.d.ts +0 -4
- package/dist/cli/commands/auth/index.d.ts.map +0 -1
- package/dist/cli/commands/auth/index.js +0 -4
- package/dist/cli/commands/auth/login.d.ts +0 -12
- package/dist/cli/commands/auth/login.d.ts.map +0 -1
- package/dist/cli/commands/auth/login.js +0 -153
- package/dist/cli/commands/auth/logout.d.ts +0 -5
- package/dist/cli/commands/auth/logout.d.ts.map +0 -1
- package/dist/cli/commands/auth/logout.js +0 -81
- package/dist/cli/commands/auth/register.d.ts +0 -3
- package/dist/cli/commands/auth/register.d.ts.map +0 -1
- package/dist/cli/commands/auth/register.js +0 -96
- package/dist/cli/commands/auth/status.d.ts +0 -2
- package/dist/cli/commands/auth/status.d.ts.map +0 -1
- package/dist/cli/commands/auth/status.js +0 -22
- package/dist/cli/commands/billing/index.d.ts +0 -2
- package/dist/cli/commands/billing/index.d.ts.map +0 -1
- package/dist/cli/commands/billing/index.js +0 -2
- package/dist/cli/commands/billing/register.d.ts +0 -3
- package/dist/cli/commands/billing/register.d.ts.map +0 -1
- package/dist/cli/commands/billing/register.js +0 -20
- package/dist/cli/commands/billing/status.d.ts +0 -8
- package/dist/cli/commands/billing/status.d.ts.map +0 -1
- package/dist/cli/commands/billing/status.js +0 -71
- package/dist/cli/commands/cloud/discovery.d.ts +0 -17
- package/dist/cli/commands/cloud/discovery.d.ts.map +0 -1
- package/dist/cli/commands/cloud/discovery.js +0 -88
- package/dist/cli/commands/deploy/client.d.ts +0 -113
- package/dist/cli/commands/deploy/client.d.ts.map +0 -1
- package/dist/cli/commands/deploy/client.js +0 -519
- package/dist/cli/commands/deploy/config.d.ts +0 -37
- package/dist/cli/commands/deploy/config.d.ts.map +0 -1
- package/dist/cli/commands/deploy/config.js +0 -144
- package/dist/cli/commands/deploy/entry-agent.d.ts +0 -3
- package/dist/cli/commands/deploy/entry-agent.d.ts.map +0 -1
- package/dist/cli/commands/deploy/entry-agent.js +0 -70
- package/dist/cli/commands/deploy/index.d.ts +0 -12
- package/dist/cli/commands/deploy/index.d.ts.map +0 -1
- package/dist/cli/commands/deploy/index.js +0 -370
- package/dist/cli/commands/deploy/links.d.ts +0 -3
- package/dist/cli/commands/deploy/links.d.ts.map +0 -1
- package/dist/cli/commands/deploy/links.js +0 -53
- package/dist/cli/commands/deploy/register.d.ts +0 -6
- package/dist/cli/commands/deploy/register.d.ts.map +0 -1
- package/dist/cli/commands/deploy/register.js +0 -128
- package/dist/cli/commands/deploy/snapshot.d.ts +0 -12
- package/dist/cli/commands/deploy/snapshot.d.ts.map +0 -1
- package/dist/cli/commands/deploy/snapshot.js +0 -76
- package/dist/cli/commands/deploy/state.d.ts +0 -13
- package/dist/cli/commands/deploy/state.d.ts.map +0 -1
- package/dist/cli/commands/deploy/state.js +0 -122
- package/dist/cli/commands/span/register.d.ts +0 -6
- package/dist/cli/commands/span/register.d.ts.map +0 -1
- package/dist/cli/commands/span/register.js +0 -25
- package/dist/cli/commands/trace/client.d.ts +0 -98
- package/dist/cli/commands/trace/client.d.ts.map +0 -1
- package/dist/cli/commands/trace/client.js +0 -150
- package/dist/cli/commands/trace/format.d.ts +0 -5
- package/dist/cli/commands/trace/format.d.ts.map +0 -1
- package/dist/cli/commands/trace/format.js +0 -58
- package/dist/cli/commands/trace/index.d.ts +0 -21
- package/dist/cli/commands/trace/index.d.ts.map +0 -1
- package/dist/cli/commands/trace/index.js +0 -49
- package/dist/cli/commands/trace/register.d.ts +0 -6
- package/dist/cli/commands/trace/register.d.ts.map +0 -1
- package/dist/cli/commands/trace/register.js +0 -71
- package/dist/webui/assets/index-DEfRFmFT.js +0 -1667
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type Command, type CommandContext } from '../command.js';
|
|
3
|
+
declare const ToolSchema: z.ZodObject<{
|
|
4
|
+
_meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
5
|
+
description: z.ZodOptional<z.ZodString>;
|
|
6
|
+
inputSchema: z.ZodUnknown;
|
|
7
|
+
name: z.ZodString;
|
|
8
|
+
title: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
export type WorkspaceTool = z.output<typeof ToolSchema>;
|
|
11
|
+
/** The levels at which a call asks the person before it runs. */
|
|
12
|
+
export declare const ASKING_LEVELS: ReadonlySet<string>;
|
|
13
|
+
/** A tool's level for one call: its action's own level, where the action decides it. */
|
|
14
|
+
export declare function toolCallLevel(tool: WorkspaceTool, input: Record<string, unknown>): string;
|
|
15
|
+
/**
|
|
16
|
+
* Agrees to a call that asks first, by `--yes` or at the terminal, and returns what to add to its
|
|
17
|
+
* input: `confirm: true` where the tool takes it, the server's sign that the person agreed.
|
|
18
|
+
*/
|
|
19
|
+
export declare function agreeToCall(context: CommandContext, call: {
|
|
20
|
+
readonly level: string;
|
|
21
|
+
readonly schema: unknown;
|
|
22
|
+
readonly title: string;
|
|
23
|
+
}, yes: boolean): Promise<{
|
|
24
|
+
confirm?: true;
|
|
25
|
+
}>;
|
|
26
|
+
/** Every workspace tool the sign-in can call, as the Dexto MCP lists them. */
|
|
27
|
+
export declare function listWorkspaceTools(context: CommandContext): Promise<WorkspaceTool[]>;
|
|
28
|
+
/** Calls a workspace tool and prints its result; a tool's own error fails the command. */
|
|
29
|
+
export declare function callWorkspaceTool(context: CommandContext, name: string, input: unknown): Promise<number>;
|
|
30
|
+
/** Calls a workspace tool for its value, without printing it; the tool's own error fails. */
|
|
31
|
+
export declare function queryWorkspaceTool(context: CommandContext, name: string, input: unknown): Promise<unknown>;
|
|
32
|
+
/** Calls a workspace tool for its structured result, without printing it. */
|
|
33
|
+
export declare function readWorkspaceTool(context: CommandContext, name: string, input: unknown): Promise<unknown>;
|
|
34
|
+
export declare const workspaceCommands: readonly Command[];
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=workspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../../src/cli/cloud/commands/workspace.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAcH,KAAK,OAAO,EACZ,KAAK,cAAc,EACtB,MAAM,eAAe,CAAC;AAEvB,QAAA,MAAM,UAAU;;;;;;iBAOd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAIxD,iEAAiE;AACjE,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAAwC,CAAC;AAEvF,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAOzF;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC7B,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAClF,GAAG,EAAE,OAAO,GACb,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC,CAQ7B;AAgBD,8EAA8E;AAC9E,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAE1F;AAoFD,0FAA0F;AAC1F,wBAAsB,iBAAiB,CACnC,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAyCD,6FAA6F;AAC7F,wBAAsB,kBAAkB,CACpC,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACf,OAAO,CAAC,OAAO,CAAC,CAMlB;AAED,6EAA6E;AAC7E,wBAAsB,iBAAiB,CACnC,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACf,OAAO,CAAC,OAAO,CAAC,CAalB;AAoHD,eAAO,MAAM,iBAAiB,EAAE,SAAS,OAAO,EAA4B,CAAC"}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
// `workspace`: the tools an agent uses in your Dexto workspace over MCP, called as you.
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { argument, BODY_OPTIONS, CommandFailure, flag, isJsonObject, MissingScopeFailure, readJsonBody, requireConsent, rerunWith, signInCommand, stringOption, UsageError, YES_OPTION, } from '../command.js';
|
|
4
|
+
const ToolSchema = z.object({
|
|
5
|
+
/** `dexto/app`, `dexto/app_kind` and `dexto/level` say which app provides the tool and how it asks. */
|
|
6
|
+
_meta: z.record(z.string(), z.unknown()).optional(),
|
|
7
|
+
description: z.string().optional(),
|
|
8
|
+
inputSchema: z.unknown(),
|
|
9
|
+
name: z.string(),
|
|
10
|
+
title: z.string().optional(),
|
|
11
|
+
});
|
|
12
|
+
const ToolListSchema = z.object({ tools: z.array(ToolSchema) });
|
|
13
|
+
/** The levels at which a call asks the person before it runs. */
|
|
14
|
+
export const ASKING_LEVELS = new Set(['act', 'approve', 'money']);
|
|
15
|
+
/** A tool's level for one call: its action's own level, where the action decides it. */
|
|
16
|
+
export function toolCallLevel(tool, input) {
|
|
17
|
+
const levels = tool._meta?.['dexto/action_levels'];
|
|
18
|
+
const actionLevel = isJsonObject(levels) && typeof input.action === 'string' ? levels[input.action] : undefined;
|
|
19
|
+
if (typeof actionLevel === 'string')
|
|
20
|
+
return actionLevel;
|
|
21
|
+
const level = tool._meta?.['dexto/level'];
|
|
22
|
+
return typeof level === 'string' ? level : 'act';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Agrees to a call that asks first, by `--yes` or at the terminal, and returns what to add to its
|
|
26
|
+
* input: `confirm: true` where the tool takes it, the server's sign that the person agreed.
|
|
27
|
+
*/
|
|
28
|
+
export async function agreeToCall(context, call, yes) {
|
|
29
|
+
if (!ASKING_LEVELS.has(call.level))
|
|
30
|
+
return {};
|
|
31
|
+
await requireConsent(context, yes, `"${call.title}" asks before it runs (level ${call.level}).`);
|
|
32
|
+
return takesConfirm(call.schema) ? { confirm: true } : {};
|
|
33
|
+
}
|
|
34
|
+
function takesConfirm(schema) {
|
|
35
|
+
if (!isJsonObject(schema))
|
|
36
|
+
return false;
|
|
37
|
+
const variants = [
|
|
38
|
+
schema,
|
|
39
|
+
...[schema.anyOf, schema.oneOf].flatMap((each) => (Array.isArray(each) ? each : [])),
|
|
40
|
+
];
|
|
41
|
+
return variants.some((variant) => isJsonObject(variant) &&
|
|
42
|
+
isJsonObject(variant.properties) &&
|
|
43
|
+
'confirm' in variant.properties);
|
|
44
|
+
}
|
|
45
|
+
/** Every workspace tool the sign-in can call, as the Dexto MCP lists them. */
|
|
46
|
+
export async function listWorkspaceTools(context) {
|
|
47
|
+
return ToolListSchema.parse(await callMcp(context, 'tools/list', {})).tools;
|
|
48
|
+
}
|
|
49
|
+
const ToolResultSchema = z.object({
|
|
50
|
+
content: z
|
|
51
|
+
.array(z.object({ text: z.string().optional(), type: z.string() }).passthrough())
|
|
52
|
+
.default([]),
|
|
53
|
+
isError: z.boolean().optional(),
|
|
54
|
+
structuredContent: z.unknown().optional(),
|
|
55
|
+
});
|
|
56
|
+
const tools = {
|
|
57
|
+
options: {
|
|
58
|
+
search: {
|
|
59
|
+
description: 'Only tools whose name or description has this text.',
|
|
60
|
+
type: 'string',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
path: ['workspace', 'tools'],
|
|
64
|
+
summary: 'List the workspace tools your sign-in can call.',
|
|
65
|
+
async run(context, input) {
|
|
66
|
+
const search = stringOption(input, 'search')?.toLowerCase();
|
|
67
|
+
const listed = (await listWorkspaceTools(context)).filter((tool) => search === undefined ||
|
|
68
|
+
tool.name.toLowerCase().includes(search) ||
|
|
69
|
+
(tool.description ?? '').toLowerCase().includes(search));
|
|
70
|
+
context.output.list({ data: listed }, [
|
|
71
|
+
{ header: 'name', value: (tool) => tool.name },
|
|
72
|
+
{
|
|
73
|
+
header: 'title',
|
|
74
|
+
value: (tool) => tool.title ?? tool.description ?? '',
|
|
75
|
+
},
|
|
76
|
+
]);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
const describe = {
|
|
80
|
+
arguments: '<tool>',
|
|
81
|
+
path: ['workspace', 'describe'],
|
|
82
|
+
summary: "Show a workspace tool's description and the input it takes.",
|
|
83
|
+
async run(context, input) {
|
|
84
|
+
const name = argument(input, 0, 'tool');
|
|
85
|
+
const tool = (await listWorkspaceTools(context)).find((each) => each.name === name);
|
|
86
|
+
if (tool === undefined)
|
|
87
|
+
throw new UsageError(`No workspace tool ${name}. List them with dexto workspace tools.`);
|
|
88
|
+
if (context.output.json)
|
|
89
|
+
return context.output.record(tool);
|
|
90
|
+
context.runtime.writeOutput(`${tool.title ?? tool.name}\n\n${tool.description ?? ''}\n\nInput:\n${JSON.stringify(tool.inputSchema, null, 2)}\n`);
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
const call = {
|
|
94
|
+
arguments: '<tool>',
|
|
95
|
+
options: { ...BODY_OPTIONS, ...YES_OPTION },
|
|
96
|
+
path: ['workspace', 'call'],
|
|
97
|
+
summary: 'Call a workspace tool with its input as JSON, such as: dexto workspace call dexto_search --data \'{"query":"invoices"}\'',
|
|
98
|
+
async run(context, input) {
|
|
99
|
+
const body = await readJsonBody(context, input);
|
|
100
|
+
if (body !== null && !isJsonObject(body))
|
|
101
|
+
throw new UsageError("A tool's input must be a JSON object.");
|
|
102
|
+
const name = argument(input, 0, 'tool');
|
|
103
|
+
const tool = (await listWorkspaceTools(context)).find((each) => each.name === name);
|
|
104
|
+
// A tool the sign-in isn't listed can't run anyway: the server refuses it and says why.
|
|
105
|
+
const agreed = tool === undefined
|
|
106
|
+
? {}
|
|
107
|
+
: await agreeToCall(context, {
|
|
108
|
+
level: toolCallLevel(tool, body ?? {}),
|
|
109
|
+
schema: tool.inputSchema,
|
|
110
|
+
title: tool.title ?? tool.name,
|
|
111
|
+
}, flag(input, 'yes'));
|
|
112
|
+
return await callWorkspaceTool(context, name, { ...body, ...agreed });
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
/** Calls a workspace tool and prints its result; a tool's own error fails the command. */
|
|
116
|
+
export async function callWorkspaceTool(context, name, input) {
|
|
117
|
+
const result = ToolResultSchema.parse(await callMcp(context, 'tools/call', { arguments: input, name }));
|
|
118
|
+
if (result.isError === true)
|
|
119
|
+
throw toolFailure(context, result);
|
|
120
|
+
if (context.output.json)
|
|
121
|
+
context.output.record(toolValue(result));
|
|
122
|
+
else {
|
|
123
|
+
const text = result.content
|
|
124
|
+
.map((part) => part.text)
|
|
125
|
+
.filter((part) => part !== undefined);
|
|
126
|
+
context.runtime.writeOutput(text.length > 0
|
|
127
|
+
? `${text.join('\n')}\n`
|
|
128
|
+
: `${JSON.stringify(result.structuredContent ?? result.content, null, 2)}\n`);
|
|
129
|
+
}
|
|
130
|
+
return 0;
|
|
131
|
+
}
|
|
132
|
+
/** A tool result's value: its structured content, else its text as JSON, else the text itself. */
|
|
133
|
+
function toolValue(result) {
|
|
134
|
+
if (result.structuredContent !== undefined)
|
|
135
|
+
return result.structuredContent;
|
|
136
|
+
const text = result.content
|
|
137
|
+
.map((part) => part.text)
|
|
138
|
+
.filter((part) => part !== undefined)
|
|
139
|
+
.join('\n');
|
|
140
|
+
try {
|
|
141
|
+
return JSON.parse(text);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return { text };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** A tool's own error as a failure: not found, a permission to grant, or a failed call. */
|
|
148
|
+
function toolFailure(context, result) {
|
|
149
|
+
const value = toolValue(result);
|
|
150
|
+
const error = isJsonObject(value) && isJsonObject(value.error) ? value.error : null;
|
|
151
|
+
const status = isJsonObject(value) ? (value.status ?? error?.code) : undefined;
|
|
152
|
+
const text = result.content
|
|
153
|
+
.map((part) => part.text)
|
|
154
|
+
.filter((part) => part !== undefined)
|
|
155
|
+
.join('\n');
|
|
156
|
+
const message = (isJsonObject(value) && typeof value.message === 'string' && value.message) ||
|
|
157
|
+
(typeof error?.message === 'string' && error.message) ||
|
|
158
|
+
text ||
|
|
159
|
+
'The tool reported an error.';
|
|
160
|
+
if (status === 'not_found')
|
|
161
|
+
return new CommandFailure('not_found', message, null);
|
|
162
|
+
const scopes = isJsonObject(value) && Array.isArray(value.requiredScopes) ? value.requiredScopes : [];
|
|
163
|
+
if (status === 'consent_required' && scopes.length > 0)
|
|
164
|
+
return new MissingScopeFailure(context, scopes.map(String).join(','), message);
|
|
165
|
+
return new CommandFailure('failed', message, null);
|
|
166
|
+
}
|
|
167
|
+
/** Calls a workspace tool for its value, without printing it; the tool's own error fails. */
|
|
168
|
+
export async function queryWorkspaceTool(context, name, input) {
|
|
169
|
+
const result = ToolResultSchema.parse(await callMcp(context, 'tools/call', { arguments: input, name }));
|
|
170
|
+
if (result.isError === true)
|
|
171
|
+
throw toolFailure(context, result);
|
|
172
|
+
return toolValue(result);
|
|
173
|
+
}
|
|
174
|
+
/** Calls a workspace tool for its structured result, without printing it. */
|
|
175
|
+
export async function readWorkspaceTool(context, name, input) {
|
|
176
|
+
const result = ToolResultSchema.parse(await callMcp(context, 'tools/call', { arguments: input, name }));
|
|
177
|
+
if (result.isError === true)
|
|
178
|
+
return null;
|
|
179
|
+
if (result.structuredContent !== undefined)
|
|
180
|
+
return result.structuredContent;
|
|
181
|
+
const text = result.content.find((part) => part.text !== undefined)?.text;
|
|
182
|
+
if (text === undefined)
|
|
183
|
+
return null;
|
|
184
|
+
try {
|
|
185
|
+
return JSON.parse(text);
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
let nextRequestId = 1;
|
|
192
|
+
/**
|
|
193
|
+
* One JSON-RPC request to the Dexto MCP with the person's token. It takes only a person's sign-in:
|
|
194
|
+
* the workspace acts as a person, never as a project key.
|
|
195
|
+
*/
|
|
196
|
+
async function callMcp(context, method, params) {
|
|
197
|
+
const connection = await context.connection();
|
|
198
|
+
if (connection.kind !== 'oauth')
|
|
199
|
+
throw new CommandFailure('needs_sign_in', "Workspace tools act as you, so an API key can't use them. Sign in as yourself.", signInCommand(context, null));
|
|
200
|
+
const response = await context.runtime.fetch(connection.login.resource, {
|
|
201
|
+
body: JSON.stringify({
|
|
202
|
+
id: nextRequestId++,
|
|
203
|
+
jsonrpc: '2.0',
|
|
204
|
+
method,
|
|
205
|
+
params,
|
|
206
|
+
}),
|
|
207
|
+
headers: {
|
|
208
|
+
accept: 'application/json, text/event-stream',
|
|
209
|
+
authorization: `Bearer ${connection.token}`,
|
|
210
|
+
'content-type': 'application/json',
|
|
211
|
+
},
|
|
212
|
+
method: 'POST',
|
|
213
|
+
signal: context.runtime.signal,
|
|
214
|
+
});
|
|
215
|
+
if (response.status === 401 || response.status === 403)
|
|
216
|
+
throw new CommandFailure('needs_sign_in', "Your sign-in can't reach the workspace. Sign in again to grant it.", signInCommand(context, null));
|
|
217
|
+
const text = await response.text();
|
|
218
|
+
if (!response.ok)
|
|
219
|
+
throw new Error(`The Dexto MCP answered HTTP ${response.status}.`);
|
|
220
|
+
const message = parseJsonRpc(response.headers.get('content-type')?.includes('text/event-stream') === true
|
|
221
|
+
? lastEventData(text)
|
|
222
|
+
: text);
|
|
223
|
+
if (message.error !== undefined)
|
|
224
|
+
throw refusalFailure(context, message.error);
|
|
225
|
+
return message.result;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* A refusal as a failure, by the kind, scope and level its `data` names. Servers that send no
|
|
229
|
+
* `data` say it only in the message, so that is read too.
|
|
230
|
+
*/
|
|
231
|
+
function refusalFailure(context, error) {
|
|
232
|
+
const data = RefusalDataSchema.safeParse(error.data).data ?? {};
|
|
233
|
+
// `scopes` when any one of several would do: asking for the first is enough.
|
|
234
|
+
const scope = data.scope ?? data.scopes?.[0] ?? MISSING_SCOPE.exec(error.message)?.[1];
|
|
235
|
+
if (scope !== undefined)
|
|
236
|
+
return new MissingScopeFailure(context, scope, data.scopes !== undefined && data.scopes.length > 1
|
|
237
|
+
? `This needs one of the ${data.scopes.join(', ')} permissions, which your sign-in doesn't have.`
|
|
238
|
+
: `This needs the ${scope} permission, which your sign-in doesn't have.`);
|
|
239
|
+
if (data.kind === 'needs_confirmation')
|
|
240
|
+
return new CommandFailure('needs_confirmation', error.message, rerunWith(context, '--yes'));
|
|
241
|
+
if (data.kind === 'not_found' ||
|
|
242
|
+
(data.kind === undefined && /\bnot found\b/iu.test(error.message)))
|
|
243
|
+
return new CommandFailure('not_found', error.message, null);
|
|
244
|
+
if (data.kind === 'forbidden' || (data.kind === undefined && error.code === -32003))
|
|
245
|
+
return new CommandFailure('needs_permission', error.message, null);
|
|
246
|
+
if (data.kind === 'invalid_arguments' ||
|
|
247
|
+
data.kind === 'unprocessable' ||
|
|
248
|
+
(data.kind === undefined && error.code === -32602))
|
|
249
|
+
return new CommandFailure('invalid_input', error.message, null);
|
|
250
|
+
return new CommandFailure('failed', error.message, null);
|
|
251
|
+
}
|
|
252
|
+
/** How the Dexto MCP refuses a tool the token's grant doesn't cover. */
|
|
253
|
+
const MISSING_SCOPE = /missing required scope: ([\w:.-]+?)\.?$/u;
|
|
254
|
+
const RefusalDataSchema = z.object({
|
|
255
|
+
kind: z.string().optional(),
|
|
256
|
+
level: z.string().optional(),
|
|
257
|
+
scope: z.string().optional(),
|
|
258
|
+
scopes: z.array(z.string()).optional(),
|
|
259
|
+
});
|
|
260
|
+
const JsonRpcResponseSchema = z.object({
|
|
261
|
+
error: z
|
|
262
|
+
.object({ code: z.number(), data: z.unknown().optional(), message: z.string() })
|
|
263
|
+
.optional(),
|
|
264
|
+
result: z.unknown().optional(),
|
|
265
|
+
});
|
|
266
|
+
function parseJsonRpc(text) {
|
|
267
|
+
return JsonRpcResponseSchema.parse(JSON.parse(text));
|
|
268
|
+
}
|
|
269
|
+
function lastEventData(stream) {
|
|
270
|
+
const data = stream
|
|
271
|
+
.split('\n')
|
|
272
|
+
.filter((line) => line.startsWith('data:'))
|
|
273
|
+
.map((line) => line.slice(5).trim());
|
|
274
|
+
const last = data.at(-1);
|
|
275
|
+
if (last === undefined)
|
|
276
|
+
throw new Error('The Dexto MCP sent no reply.');
|
|
277
|
+
return last;
|
|
278
|
+
}
|
|
279
|
+
export const workspaceCommands = [tools, describe, call];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { dextoAccounts } from '@dexto/agent-management';
|
|
2
|
+
/** The global `--api-key`, `--api-base-url`, `--profile` and `--project` values, when given. */
|
|
3
|
+
export interface ConnectionOverrides {
|
|
4
|
+
readonly apiBaseUrl: string | null;
|
|
5
|
+
readonly apiKey: string | null;
|
|
6
|
+
readonly cloudProject: string | null;
|
|
7
|
+
readonly profile: string | null;
|
|
8
|
+
}
|
|
9
|
+
export type Connection = {
|
|
10
|
+
readonly apiBaseUrl: string;
|
|
11
|
+
/** The Cloud project a person's token acts in: --project, DEXTO_CLOUD_PROJECT or the saved one. */
|
|
12
|
+
readonly cloudProject: string | null;
|
|
13
|
+
/** The profile whose sign-in this is, or that --profile or DEXTO_PROFILE named. */
|
|
14
|
+
readonly profile: string;
|
|
15
|
+
readonly source: dextoAccounts.CredentialSource;
|
|
16
|
+
} & ({
|
|
17
|
+
readonly kind: 'api_key';
|
|
18
|
+
readonly token: string;
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: 'oauth';
|
|
21
|
+
readonly token: string;
|
|
22
|
+
readonly login: dextoAccounts.OAuthLogin;
|
|
23
|
+
});
|
|
24
|
+
export interface ResolveConnectionInput {
|
|
25
|
+
/** ~/.dexto/accounts */
|
|
26
|
+
readonly dir: string;
|
|
27
|
+
readonly environment: Readonly<Record<string, string | undefined>>;
|
|
28
|
+
readonly overrides: ConnectionOverrides;
|
|
29
|
+
readonly refresh: (login: dextoAccounts.OAuthLogin) => Promise<dextoAccounts.OAuthLogin>;
|
|
30
|
+
}
|
|
31
|
+
/** --api-key, then DEXTO_API_KEY, then the profile's sign-in, refreshed when due; null when none. */
|
|
32
|
+
export declare function resolveConnection(input: ResolveConnectionInput): Promise<Connection | null>;
|
|
33
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/cli/cloud/connection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAIxD,gGAAgG;AAChG,MAAM,WAAW,mBAAmB;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,MAAM,UAAU,GAAG;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,mGAAmG;IACnG,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,mFAAmF;IACnF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC;CACnD,GAAG,CACE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,UAAU,CAAA;CAAE,CACjG,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACnC,wBAAwB;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IACnE,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,UAAU,KAAK,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;CAC5F;AAED,qGAAqG;AACrG,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgCjG"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// How a cloud command reaches Dexto: the sign-in or key, the API origin and the Cloud project.
|
|
2
|
+
import { dextoAccounts } from '@dexto/agent-management';
|
|
3
|
+
const DEFAULT_API_BASE_URL = 'https://api.dexto.ai';
|
|
4
|
+
/** --api-key, then DEXTO_API_KEY, then the profile's sign-in, refreshed when due; null when none. */
|
|
5
|
+
export async function resolveConnection(input) {
|
|
6
|
+
const credential = await dextoAccounts.resolveCredential({
|
|
7
|
+
dir: input.dir,
|
|
8
|
+
apiKey: input.overrides.apiKey,
|
|
9
|
+
profile: input.overrides.profile,
|
|
10
|
+
environment: input.environment,
|
|
11
|
+
refresh: input.refresh,
|
|
12
|
+
});
|
|
13
|
+
if (credential === null)
|
|
14
|
+
return null;
|
|
15
|
+
const saved = credential.kind === 'oauth'
|
|
16
|
+
? credential.login
|
|
17
|
+
: credential.source === 'login'
|
|
18
|
+
? await dextoAccounts.readLogin(input.dir, credential.profile)
|
|
19
|
+
: null;
|
|
20
|
+
const apiBaseUrl = (input.overrides.apiBaseUrl ??
|
|
21
|
+
nonEmpty(input.environment.DEXTO_API_BASE_URL) ??
|
|
22
|
+
saved?.apiBaseUrl ??
|
|
23
|
+
DEFAULT_API_BASE_URL).replace(/\/+$/u, '');
|
|
24
|
+
const named = input.overrides.cloudProject ?? nonEmpty(input.environment.DEXTO_CLOUD_PROJECT);
|
|
25
|
+
const base = { apiBaseUrl, profile: credential.profile, source: credential.source };
|
|
26
|
+
return credential.kind === 'oauth'
|
|
27
|
+
? {
|
|
28
|
+
...base,
|
|
29
|
+
kind: 'oauth',
|
|
30
|
+
token: credential.token,
|
|
31
|
+
login: credential.login,
|
|
32
|
+
cloudProject: named ?? credential.login.cloudProject?.id ?? null,
|
|
33
|
+
}
|
|
34
|
+
: { ...base, kind: 'api_key', token: credential.token, cloudProject: named };
|
|
35
|
+
}
|
|
36
|
+
function nonEmpty(value) {
|
|
37
|
+
return value === undefined || value.length === 0 ? null : value;
|
|
38
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { CommandContext } from './command.js';
|
|
2
|
+
interface RunUsage {
|
|
3
|
+
readonly credits: number;
|
|
4
|
+
readonly input_tokens: number;
|
|
5
|
+
readonly output_tokens: number;
|
|
6
|
+
}
|
|
7
|
+
/** The events a run sends that the CLI shows; the API documents each. */
|
|
8
|
+
export type AgentEvent = {
|
|
9
|
+
readonly type: 'run.started';
|
|
10
|
+
readonly run_id: string;
|
|
11
|
+
} | {
|
|
12
|
+
readonly type: 'message.delta';
|
|
13
|
+
readonly run_id: string;
|
|
14
|
+
readonly text: string;
|
|
15
|
+
} | {
|
|
16
|
+
readonly type: 'message.completed';
|
|
17
|
+
readonly run_id: string;
|
|
18
|
+
readonly text: string;
|
|
19
|
+
} | {
|
|
20
|
+
readonly type: 'tool.started';
|
|
21
|
+
readonly run_id: string;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly arguments: unknown;
|
|
24
|
+
} | {
|
|
25
|
+
readonly type: 'tool.completed';
|
|
26
|
+
readonly run_id: string;
|
|
27
|
+
readonly name: string;
|
|
28
|
+
readonly status: string;
|
|
29
|
+
readonly error: {
|
|
30
|
+
readonly code: string;
|
|
31
|
+
readonly message: string;
|
|
32
|
+
} | null;
|
|
33
|
+
} | {
|
|
34
|
+
readonly type: 'approval.requested';
|
|
35
|
+
readonly run_id: string;
|
|
36
|
+
readonly approval_id: string;
|
|
37
|
+
readonly tool_name: string | null;
|
|
38
|
+
readonly input: unknown;
|
|
39
|
+
} | {
|
|
40
|
+
readonly type: 'approval.resolved';
|
|
41
|
+
readonly run_id: string;
|
|
42
|
+
} | {
|
|
43
|
+
readonly type: 'run.completed';
|
|
44
|
+
readonly run_id: string;
|
|
45
|
+
readonly stop_reason: string;
|
|
46
|
+
readonly usage: RunUsage;
|
|
47
|
+
} | {
|
|
48
|
+
readonly type: 'run.failed';
|
|
49
|
+
readonly run_id: string;
|
|
50
|
+
readonly error: {
|
|
51
|
+
readonly code: string;
|
|
52
|
+
readonly message: string;
|
|
53
|
+
};
|
|
54
|
+
} | {
|
|
55
|
+
readonly type: 'run.cancelled';
|
|
56
|
+
readonly run_id: string;
|
|
57
|
+
};
|
|
58
|
+
/** Parses one SSE block; comments, blocks without data and unknown events are skipped. */
|
|
59
|
+
export declare function parseEventBlock(block: string): AgentEvent | null;
|
|
60
|
+
/** The session's events until the stream closes or `signal` aborts. */
|
|
61
|
+
export declare function sessionEvents(context: CommandContext, agentId: string, sessionId: string, signal: AbortSignal): AsyncGenerator<AgentEvent>;
|
|
62
|
+
export {};
|
|
63
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/cli/cloud/events.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnD,UAAU,QAAQ;IACd,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAClC;AAED,yEAAyE;AACzE,MAAM,MAAM,UAAU,GAChB;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClF;IAAE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtF;IACI,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC/B,GACD;IACI,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC9E,GACD;IACI,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CAC3B,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC/D;IACI,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;CAC5B,GACD;IACI,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACvE,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AA4BlE,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAYhE;AAED,uEAAuE;AACvE,wBAAuB,aAAa,CAChC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,GACpB,cAAc,CAAC,UAAU,CAAC,CA6B5B"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// A session's events, as `GET /v1/agents/{agent_id}/sessions/{session_id}/events` streams them.
|
|
2
|
+
import { sendV1, v1Failure } from './v1.js';
|
|
3
|
+
const TYPES = new Set([
|
|
4
|
+
'run.started',
|
|
5
|
+
'message.delta',
|
|
6
|
+
'message.completed',
|
|
7
|
+
'tool.started',
|
|
8
|
+
'tool.completed',
|
|
9
|
+
'approval.requested',
|
|
10
|
+
'approval.resolved',
|
|
11
|
+
'run.completed',
|
|
12
|
+
'run.failed',
|
|
13
|
+
'run.cancelled',
|
|
14
|
+
]);
|
|
15
|
+
/** A known event; the server's own contract carries the rest of its fields. */
|
|
16
|
+
function isAgentEvent(value) {
|
|
17
|
+
return (typeof value === 'object' &&
|
|
18
|
+
value !== null &&
|
|
19
|
+
'type' in value &&
|
|
20
|
+
typeof value.type === 'string' &&
|
|
21
|
+
TYPES.has(value.type) &&
|
|
22
|
+
'run_id' in value &&
|
|
23
|
+
typeof value.run_id === 'string');
|
|
24
|
+
}
|
|
25
|
+
/** Parses one SSE block; comments, blocks without data and unknown events are skipped. */
|
|
26
|
+
export function parseEventBlock(block) {
|
|
27
|
+
const data = [];
|
|
28
|
+
for (const line of block.split('\n'))
|
|
29
|
+
if (line.startsWith('data:'))
|
|
30
|
+
data.push(line.slice(5).trimStart());
|
|
31
|
+
if (data.length === 0)
|
|
32
|
+
return null;
|
|
33
|
+
let value;
|
|
34
|
+
try {
|
|
35
|
+
value = JSON.parse(data.join('\n'));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return isAgentEvent(value) ? value : null;
|
|
41
|
+
}
|
|
42
|
+
/** The session's events until the stream closes or `signal` aborts. */
|
|
43
|
+
export async function* sessionEvents(context, agentId, sessionId, signal) {
|
|
44
|
+
const response = await sendV1(context, 'GET', `/v1/agents/${encodeURIComponent(agentId)}/sessions/${encodeURIComponent(sessionId)}/events`, { body: null, headers: { accept: 'text/event-stream' } }, signal);
|
|
45
|
+
if (!response.ok)
|
|
46
|
+
throw v1Failure(context, response.status, await response.text());
|
|
47
|
+
if (response.body === null)
|
|
48
|
+
return;
|
|
49
|
+
const reader = response.body.pipeThrough(new globalThis.TextDecoderStream()).getReader();
|
|
50
|
+
let buffer = '';
|
|
51
|
+
try {
|
|
52
|
+
for (;;) {
|
|
53
|
+
const { done, value } = await reader.read();
|
|
54
|
+
if (done)
|
|
55
|
+
break;
|
|
56
|
+
buffer += value;
|
|
57
|
+
const blocks = buffer.split('\n\n');
|
|
58
|
+
buffer = blocks.pop() ?? '';
|
|
59
|
+
for (const block of blocks) {
|
|
60
|
+
const event = parseEventBlock(block);
|
|
61
|
+
if (event !== null)
|
|
62
|
+
yield event;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const last = parseEventBlock(buffer);
|
|
66
|
+
if (last !== null)
|
|
67
|
+
yield last;
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
await reader.cancel().catch(() => undefined);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Command } from './command.js';
|
|
2
|
+
import { type SignInFor } from './commands/account.js';
|
|
3
|
+
import type { CloudHost, Group } from './run.js';
|
|
4
|
+
/** Help's areas: what `dexto cloud` builds with. */
|
|
5
|
+
export declare const CLOUD_GROUPS: Readonly<Record<string, readonly Group[]>>;
|
|
6
|
+
/** Every ported cloud command; `dir` is where sign-ins are saved. */
|
|
7
|
+
export declare function cloudCommands(dir: string, signIn: SignInFor): readonly Command[];
|
|
8
|
+
export declare function nodeCloudHost(signal: AbortSignal): CloudHost;
|
|
9
|
+
//# sourceMappingURL=host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../../src/cli/cloud/host.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAoBxE,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAIjD,oDAAoD;AACpD,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC,CAgBnE,CAAC;AAEF,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,SAAS,OAAO,EAAE,CAuBhF;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAyC5D"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// The cloud commands on this machine: the sign-in under ~/.dexto/accounts and Dexto's public API.
|
|
2
|
+
import { dextoGateway } from '@dexto/agent-management';
|
|
3
|
+
import { getDextoGlobalPath } from '@dexto/core';
|
|
4
|
+
import { accountCommands } from './commands/account.js';
|
|
5
|
+
import { agentCommands } from './commands/agents.js';
|
|
6
|
+
import { apiCommands } from './commands/api.js';
|
|
7
|
+
import { chatCommands } from './commands/chats.js';
|
|
8
|
+
import { automationCommands } from './commands/automations.js';
|
|
9
|
+
import { dataDeletionCommands } from './commands/data-deletions.js';
|
|
10
|
+
import { deployCommands } from './commands/deploys.js';
|
|
11
|
+
import { driveCommands } from './commands/drive.js';
|
|
12
|
+
import { findCommands } from './commands/find.js';
|
|
13
|
+
import { profileCommands } from './commands/profile.js';
|
|
14
|
+
import { publishCommands } from './commands/publish.js';
|
|
15
|
+
import { skillCommands } from './commands/skills.js';
|
|
16
|
+
import { fileCommands } from './commands/files.js';
|
|
17
|
+
import { modelCommands } from './commands/models.js';
|
|
18
|
+
import { projectCommands, projectsUse } from './commands/projects.js';
|
|
19
|
+
import { sandboxCommands } from './commands/sandboxes.js';
|
|
20
|
+
import { secretCommands } from './commands/secrets.js';
|
|
21
|
+
import { webCommands } from './commands/web.js';
|
|
22
|
+
import { workspaceCommands } from './commands/workspace.js';
|
|
23
|
+
import { resolveConnection } from './connection.js';
|
|
24
|
+
import { nodeCloudRuntime } from './runtime.js';
|
|
25
|
+
import { DEXTO_CREDITS_URL } from '../auth/constants.js';
|
|
26
|
+
/** Help's areas: what `dexto cloud` builds with. */
|
|
27
|
+
export const CLOUD_GROUPS = {
|
|
28
|
+
cloud: [
|
|
29
|
+
{ name: 'projects', summary: 'List, create and choose Cloud projects' },
|
|
30
|
+
{ name: 'agents', summary: 'Define agents, chat with them, read their sessions and runs' },
|
|
31
|
+
{ name: 'automations', summary: 'Run agents on a schedule or a webhook' },
|
|
32
|
+
{ name: 'files', summary: "Upload, download, share and delete the project's files" },
|
|
33
|
+
{ name: 'sandboxes', summary: 'Create sandboxes, run commands in them and move files' },
|
|
34
|
+
{ name: 'secrets', summary: 'Credentials agents use without seeing them' },
|
|
35
|
+
{ name: 'sites', summary: 'Deploy, list and delete Sites, packed with their own packer' },
|
|
36
|
+
{ name: 'functions', summary: 'Deploy and list Functions, packed with their own packer' },
|
|
37
|
+
{ name: 'models', summary: 'Run text and media models, and see media runs' },
|
|
38
|
+
{ name: 'search', summary: 'Search the web' },
|
|
39
|
+
{ name: 'fetch', summary: 'Read web pages' },
|
|
40
|
+
{ name: 'data-deletions', summary: "Delete an end user's or agent's data" },
|
|
41
|
+
{ name: 'api', summary: 'Call any /v1 operation directly' },
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
/** Every ported cloud command; `dir` is where sign-ins are saved. */
|
|
45
|
+
export function cloudCommands(dir, signIn) {
|
|
46
|
+
return [
|
|
47
|
+
...accountCommands(signIn, DEXTO_CREDITS_URL),
|
|
48
|
+
...projectCommands,
|
|
49
|
+
projectsUse(dir),
|
|
50
|
+
...agentCommands,
|
|
51
|
+
...automationCommands,
|
|
52
|
+
...fileCommands,
|
|
53
|
+
...sandboxCommands,
|
|
54
|
+
...secretCommands,
|
|
55
|
+
...deployCommands,
|
|
56
|
+
...modelCommands,
|
|
57
|
+
...webCommands,
|
|
58
|
+
...dataDeletionCommands,
|
|
59
|
+
...apiCommands,
|
|
60
|
+
...workspaceCommands,
|
|
61
|
+
...driveCommands,
|
|
62
|
+
...findCommands,
|
|
63
|
+
...profileCommands,
|
|
64
|
+
...publishCommands,
|
|
65
|
+
...skillCommands,
|
|
66
|
+
...chatCommands,
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
export function nodeCloudHost(signal) {
|
|
70
|
+
const dir = getDextoGlobalPath('accounts');
|
|
71
|
+
const runtime = nodeCloudRuntime(signal);
|
|
72
|
+
const gateway = dextoGateway.defaultDextoGatewayOptions();
|
|
73
|
+
const signIn = async (io) => (await import('../commands/auth/sign-in-context.js')).nodeSignInContext(io);
|
|
74
|
+
return {
|
|
75
|
+
commands: cloudCommands(dir, signIn),
|
|
76
|
+
signIn,
|
|
77
|
+
groups: CLOUD_GROUPS,
|
|
78
|
+
runtime,
|
|
79
|
+
resolveConnection: (overrides) => resolveConnection({
|
|
80
|
+
dir,
|
|
81
|
+
environment: runtime.environment,
|
|
82
|
+
overrides,
|
|
83
|
+
refresh: gateway.refresh,
|
|
84
|
+
}),
|
|
85
|
+
signInForScope: async (overrides, scope) => {
|
|
86
|
+
const { login } = await import('../commands/auth/sign-in-commands.js');
|
|
87
|
+
// The sign-in's own words go to stderr: stdout is the command that runs again.
|
|
88
|
+
const toStderr = (text) => runtime.writeError(`${text}\n`);
|
|
89
|
+
await login(await signIn({
|
|
90
|
+
result: (_value, text) => toStderr(text),
|
|
91
|
+
note: toStderr,
|
|
92
|
+
confirm: async () => false,
|
|
93
|
+
signal,
|
|
94
|
+
}), {
|
|
95
|
+
profile: overrides.profile,
|
|
96
|
+
org: null,
|
|
97
|
+
device: false,
|
|
98
|
+
browser: true,
|
|
99
|
+
scopes: [scope],
|
|
100
|
+
apiKey: null,
|
|
101
|
+
});
|
|
102
|
+
return true;
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|