@vendoai/vendo 0.4.2 → 0.4.4
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/capability-misses.js +2 -3
- package/dist/cli/cloud/client.d.ts +2 -5
- package/dist/cli/cloud/client.js +4 -4
- package/dist/cli/cloud/device-login.d.ts +11 -0
- package/dist/cli/cloud/device-login.js +52 -1
- package/dist/cli/dep-versions.d.ts +1 -1
- package/dist/cli/dep-versions.js +1 -1
- package/dist/cli/doctor-codes.d.ts +7 -0
- package/dist/cli/doctor-codes.js +7 -0
- package/dist/cli/doctor-live.js +11 -1
- package/dist/cli/doctor.js +122 -11
- package/dist/cli/extract/apply.js +1 -1
- package/dist/cli/extract/delegate.js +9 -1
- package/dist/cli/extract/extraction.d.ts +4 -0
- package/dist/cli/extract/extraction.js +29 -2
- package/dist/cli/extract/harness.d.ts +12 -0
- package/dist/cli/extract/harness.js +3 -0
- package/dist/cli/extract/stages.js +5 -1
- package/dist/cli/framework.d.ts +17 -2
- package/dist/cli/framework.js +32 -5
- package/dist/cli/init-scaffolds.d.ts +32 -1
- package/dist/cli/init-scaffolds.js +153 -9
- package/dist/cli/init.d.ts +14 -4
- package/dist/cli/init.js +212 -43
- package/dist/cli/playground/app/fake-client.js +11 -5
- package/dist/cli/playground/app/main.js +23 -13
- package/dist/cli/playground/app/scenario-mount.js +4 -1
- package/dist/cli/playground/app/theme-editor.js +27 -27
- package/dist/cli/playground/bundle.gen.d.ts +1 -1
- package/dist/cli/playground/bundle.gen.js +1 -1
- package/dist/cli/playground/embed-bundle.gen.d.ts +1 -1
- package/dist/cli/playground/embed-bundle.gen.js +1 -1
- package/dist/cli/shared.d.ts +1 -1
- package/dist/cli/shared.js +1 -1
- package/dist/cli/sync.d.ts +1 -1
- package/dist/cli/sync.js +1 -1
- package/dist/cloud-apps.js +2 -1
- package/dist/cloud-key-fetch.d.ts +16 -0
- package/dist/cloud-key-fetch.js +40 -0
- package/dist/cloud-tools.js +2 -1
- package/dist/connections.js +2 -2
- package/dist/dev-creds/model-edge.d.ts +21 -0
- package/dist/dev-creds/model-edge.js +24 -0
- package/dist/hosted-store.js +2 -1
- package/dist/mastra.js +71 -2
- package/dist/react.d.ts +1 -0
- package/dist/react.js +7 -0
- package/dist/refine.js +2 -1
- package/dist/sandbox.js +2 -2
- package/dist/server.d.ts +1 -1
- package/dist/server.js +56 -22
- package/dist/wire/apps.js +30 -1
- package/dist/wire/shared.d.ts +2 -2
- package/dist/wire/shared.js +1 -1
- package/package.json +20 -11
package/dist/cli/shared.d.ts
CHANGED
package/dist/cli/shared.js
CHANGED
|
@@ -4,7 +4,7 @@ import { dirname, join } from "node:path";
|
|
|
4
4
|
import { createInterface } from "node:readline/promises";
|
|
5
5
|
import { stdin, stdout } from "node:process";
|
|
6
6
|
import { initTelemetry, repoHost } from "@vendoai/telemetry";
|
|
7
|
-
export const CLI_VERSION = "0.4.
|
|
7
|
+
export const CLI_VERSION = "0.4.4";
|
|
8
8
|
export const consoleOutput = {
|
|
9
9
|
log: (message) => console.log(message),
|
|
10
10
|
error: (message) => console.error(message),
|
package/dist/cli/sync.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { vendoSync, type SyncReportWithWarnings } from "@vendoai/actions";
|
|
1
|
+
import { vendoSync, type SyncReportWithWarnings } from "@vendoai/actions/sync";
|
|
2
2
|
import type { ToolImpact } from "../sync-impact.js";
|
|
3
3
|
import { type Output, type TelemetryOptions } from "./shared.js";
|
|
4
4
|
export interface SyncReportPayload {
|
package/dist/cli/sync.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { join, resolve } from "node:path";
|
|
2
|
-
import { vendoSync } from "@vendoai/actions";
|
|
2
|
+
import { vendoSync } from "@vendoai/actions/sync";
|
|
3
3
|
import { pushSyncReport } from "./cloud/services.js";
|
|
4
4
|
import { syncSemantics } from "./semantics.js";
|
|
5
5
|
import { consoleOutput, withCommandRun } from "./shared.js";
|
package/dist/cloud-apps.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { publishRecordSchema, shareSnapshotSchema, } from "@vendoai/apps";
|
|
2
2
|
import { consoleSender, raiseCloudError } from "./cloud-console.js";
|
|
3
|
+
import { defaultFetch } from "@vendoai/core";
|
|
3
4
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
4
5
|
/** The console mounts the share/publish surface here. */
|
|
5
6
|
const CONSOLE_APPS_PATH = "/api/v1/apps";
|
|
@@ -17,7 +18,7 @@ export function cloudApps(options) {
|
|
|
17
18
|
mountPath: CONSOLE_APPS_PATH,
|
|
18
19
|
apiKey: options.apiKey,
|
|
19
20
|
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
20
|
-
fetchImpl: options.fetch ??
|
|
21
|
+
fetchImpl: options.fetch ?? defaultFetch,
|
|
21
22
|
raise: raiseAppsError,
|
|
22
23
|
});
|
|
23
24
|
const post = async (path, appId, doc, schema) => {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface CloudUrlOptions {
|
|
2
|
+
apiUrl?: string;
|
|
3
|
+
env?: Record<string, string | undefined>;
|
|
4
|
+
}
|
|
5
|
+
export declare function resolveCloudBaseUrl(options?: CloudUrlOptions): string;
|
|
6
|
+
export interface CloudKeyFetchOptions extends CloudUrlOptions {
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
method?: string;
|
|
9
|
+
body?: unknown;
|
|
10
|
+
fetchImpl?: typeof fetch;
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
}
|
|
13
|
+
/** POST/GET a console API path with VENDO_API_KEY bearer auth. The console's
|
|
14
|
+
* shared auth middleware upserts deployment inventory and meters usage from
|
|
15
|
+
* the identity headers on real service calls (deployment-identity.ts). */
|
|
16
|
+
export declare function cloudKeyFetch<T = unknown>(path: string, options?: CloudKeyFetchOptions): Promise<T>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Portable key-authenticated console calls for RUNTIME code (capability
|
|
2
|
+
* misses today). The CLI's cloudFetch adds user sessions, refresh, and disk
|
|
3
|
+
* state on top — Node-only concerns that used to ride into Worker bundles
|
|
4
|
+
* whenever runtime code borrowed it. Keep this module free of node builtins
|
|
5
|
+
* and CLI imports; the portability gate bundles it. */
|
|
6
|
+
import { defaultFetch } from "@vendoai/core";
|
|
7
|
+
import { deploymentIdentityHeaders } from "./deployment-identity.js";
|
|
8
|
+
import { VERSION } from "./wire/shared.js";
|
|
9
|
+
const DEFAULT_CLOUD_URL = "https://console.vendo.run";
|
|
10
|
+
const processEnv = () => globalThis.process?.env ?? {};
|
|
11
|
+
export function resolveCloudBaseUrl(options = {}) {
|
|
12
|
+
const value = options.apiUrl ?? (options.env ?? processEnv()).VENDO_CLOUD_URL ?? DEFAULT_CLOUD_URL;
|
|
13
|
+
return value.replace(/\/+$/, "");
|
|
14
|
+
}
|
|
15
|
+
/** POST/GET a console API path with VENDO_API_KEY bearer auth. The console's
|
|
16
|
+
* shared auth middleware upserts deployment inventory and meters usage from
|
|
17
|
+
* the identity headers on real service calls (deployment-identity.ts). */
|
|
18
|
+
export async function cloudKeyFetch(path, options = {}) {
|
|
19
|
+
const token = options.apiKey ?? (options.env ?? processEnv()).VENDO_API_KEY;
|
|
20
|
+
if (token === undefined || token === "") {
|
|
21
|
+
throw new Error("Vendo Cloud key call without a key: pass apiKey or set VENDO_API_KEY");
|
|
22
|
+
}
|
|
23
|
+
const headers = {
|
|
24
|
+
accept: "application/json",
|
|
25
|
+
authorization: `Bearer ${token}`,
|
|
26
|
+
"user-agent": `vendo-cli/${VERSION}`,
|
|
27
|
+
...(options.body === undefined ? {} : { "content-type": "application/json" }),
|
|
28
|
+
...(await deploymentIdentityHeaders()),
|
|
29
|
+
};
|
|
30
|
+
const response = await (options.fetchImpl ?? defaultFetch)(`${resolveCloudBaseUrl(options)}${path}`, {
|
|
31
|
+
method: options.method ?? (options.body === undefined ? "GET" : "POST"),
|
|
32
|
+
headers,
|
|
33
|
+
body: options.body === undefined ? undefined : JSON.stringify(options.body),
|
|
34
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
35
|
+
});
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
throw new Error(`Vendo Cloud ${path} answered ${response.status}`);
|
|
38
|
+
}
|
|
39
|
+
return await response.json();
|
|
40
|
+
}
|
package/dist/cloud-tools.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { composioToolRisk, normalizeToolName } from "@vendoai/actions";
|
|
2
2
|
import { deploymentIdentityHeaders } from "./deployment-identity.js";
|
|
3
|
+
import { defaultFetch } from "@vendoai/core";
|
|
3
4
|
function errorOutcome(message) {
|
|
4
5
|
return { status: "error", error: { code: "connector-error", message } };
|
|
5
6
|
}
|
|
@@ -8,7 +9,7 @@ function withIdentity(outcome, identity) {
|
|
|
8
9
|
}
|
|
9
10
|
export function cloudTools(options) {
|
|
10
11
|
const base = (options.baseUrl ?? "https://console.vendo.run").replace(/\/$/, "");
|
|
11
|
-
const fetchImpl = options.fetch ??
|
|
12
|
+
const fetchImpl = options.fetch ?? defaultFetch;
|
|
12
13
|
let normalizedToRaw = new Map();
|
|
13
14
|
async function cloudFetch(path, init) {
|
|
14
15
|
const response = await fetchImpl(`${base}${path}`, {
|
package/dist/connections.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { VendoError } from "@vendoai/core";
|
|
1
|
+
import { defaultFetch, VendoError } from "@vendoai/core";
|
|
2
2
|
import { consoleSender, raiseCloudError } from "./cloud-console.js";
|
|
3
3
|
/** Subjects the runtime mints for machine principals (automations webhook
|
|
4
4
|
* triggers today; the reserved `vendo:` namespace going forward). A synthetic
|
|
@@ -95,7 +95,7 @@ const raiseConnectionsError = (response) => raiseCloudError(response, "connectio
|
|
|
95
95
|
* the wire it must serve. */
|
|
96
96
|
export function cloudConnections(options) {
|
|
97
97
|
const base = (options.baseUrl ?? "https://console.vendo.run").replace(/\/$/, "");
|
|
98
|
-
const fetchImpl = options.fetch ??
|
|
98
|
+
const fetchImpl = options.fetch ?? defaultFetch;
|
|
99
99
|
// The key-authed console sender (cloud-console.ts): Bearer auth + deployment
|
|
100
100
|
// identity (the console meters usage from real traffic) + per-request abort
|
|
101
101
|
// timeout, raising through the shared error table on any non-2xx.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Web-standard-runtime build of the dev credential ladder, selected by the
|
|
2
|
+
* package's `worker`/`workerd`/`edge-light`/`browser` import conditions
|
|
3
|
+
* (see `#dev-creds/model` in package.json).
|
|
4
|
+
*
|
|
5
|
+
* The real ladder is Node by design: it resolves the host's own @ai-sdk
|
|
6
|
+
* provider install via createRequire from the project root, reads `vendo
|
|
7
|
+
* login` sessions off disk, and anchors on process.cwd(). None of that
|
|
8
|
+
* exists inside a Worker bundle — Mohamed's field report had the ladder
|
|
9
|
+
* dying on runtime require.resolve under Wrangler even with VENDO_API_KEY
|
|
10
|
+
* set. On these runtimes the model seam is explicit by contract: the host
|
|
11
|
+
* wiring constructs the provider (init generates it; the Cloud gateway is
|
|
12
|
+
* the stock Anthropic provider pointed at the console). The ladder's edge
|
|
13
|
+
* build therefore resolves to honest guidance instead of half-working
|
|
14
|
+
* magic. Keep this module free of node builtins and CLI imports; the
|
|
15
|
+
* portability gate bundles it. */
|
|
16
|
+
import type { LanguageModel } from "ai";
|
|
17
|
+
import type { DevModelOptions } from "./model.js";
|
|
18
|
+
export type { DevModelOptions };
|
|
19
|
+
/** Same seam as the Node build; announces its unavailability once on first
|
|
20
|
+
* use through the server log, like the Node ladder's unavailable rung. */
|
|
21
|
+
export declare function devModel(_options?: DevModelOptions): LanguageModel;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const EDGE_MESSAGE = "the dev model ladder needs Node (it resolves the host's provider install and dev credentials from disk); "
|
|
2
|
+
+ "on this runtime pass `model:` to createVendo explicitly — with a Vendo Cloud key that is the stock Anthropic "
|
|
3
|
+
+ "provider pointed at the console gateway: createAnthropic({ apiKey: VENDO_API_KEY, baseURL: `${VENDO_CLOUD_URL ?? \"https://console.vendo.run\"}/api/v1` })(\"vendo-default\")";
|
|
4
|
+
/** Same seam as the Node build; announces its unavailability once on first
|
|
5
|
+
* use through the server log, like the Node ladder's unavailable rung. */
|
|
6
|
+
export function devModel(_options = {}) {
|
|
7
|
+
let announced = false;
|
|
8
|
+
const refuse = () => {
|
|
9
|
+
if (!announced) {
|
|
10
|
+
announced = true;
|
|
11
|
+
console.error(`[vendo] model: ${EDGE_MESSAGE}`);
|
|
12
|
+
}
|
|
13
|
+
throw new Error(EDGE_MESSAGE);
|
|
14
|
+
};
|
|
15
|
+
const model = {
|
|
16
|
+
specificationVersion: "v3",
|
|
17
|
+
provider: "vendo-dev",
|
|
18
|
+
modelId: "dev-env",
|
|
19
|
+
supportedUrls: {},
|
|
20
|
+
doGenerate: () => Promise.resolve().then(refuse),
|
|
21
|
+
doStream: () => Promise.resolve().then(refuse),
|
|
22
|
+
};
|
|
23
|
+
return model;
|
|
24
|
+
}
|
package/dist/hosted-store.js
CHANGED
|
@@ -2,6 +2,7 @@ import { vendoRecordSchema, } from "@vendoai/core";
|
|
|
2
2
|
import { DEDICATED_RECORD_COLLECTIONS, RESERVED_COLLECTIONS, } from "@vendoai/store";
|
|
3
3
|
import { consoleSender, raiseCloudError, toArrayBuffer } from "./cloud-console.js";
|
|
4
4
|
import { deploymentIdentityHeaders } from "./deployment-identity.js";
|
|
5
|
+
import { defaultFetch } from "@vendoai/core";
|
|
5
6
|
/** The console mounts the hosted-store surface here
|
|
6
7
|
* (apps/console/app/api/v1/store/*). */
|
|
7
8
|
const CONSOLE_STORE_PATH = "/api/v1/store";
|
|
@@ -77,7 +78,7 @@ function parseNullableRecord(value) {
|
|
|
77
78
|
export function hostedStore(options) {
|
|
78
79
|
const base = (options.baseUrl ?? "https://console.vendo.run").replace(/\/$/, "");
|
|
79
80
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
80
|
-
const fetchImpl = options.fetch ??
|
|
81
|
+
const fetchImpl = options.fetch ?? defaultFetch;
|
|
81
82
|
const send = consoleSender({
|
|
82
83
|
base,
|
|
83
84
|
mountPath: CONSOLE_STORE_PATH,
|
package/dist/mastra.js
CHANGED
|
@@ -29,6 +29,74 @@ export const VENDO_PRINCIPAL_KEY = "vendo-principal";
|
|
|
29
29
|
/** Optional request-context key carrying the host session id into Vendo's
|
|
30
30
|
* audit trail; unset, the shim mints one per call. */
|
|
31
31
|
export const VENDO_SESSION_KEY = "vendo-session-id";
|
|
32
|
+
/** The bridge property carrying an OPEN tool's arguments (see
|
|
33
|
+
* {@link isOpenObjectSchema}). */
|
|
34
|
+
const OPEN_ARGS_KEY = "args";
|
|
35
|
+
/**
|
|
36
|
+
* An OPEN tool input: an object schema with no declared properties that
|
|
37
|
+
* accepts arbitrary fields (extraction emits these for routes whose body shape
|
|
38
|
+
* it cannot type, e.g. `{type:"object", properties:{}, additionalProperties:
|
|
39
|
+
* true}`). Mastra's provider schema-compat layers hard-close every object node
|
|
40
|
+
* for strict-mode providers (the OpenAI layer sets `additionalProperties:
|
|
41
|
+
* false` on all of them), so an open schema reaches the model as "this tool
|
|
42
|
+
* takes NO arguments" — and the model dutifully calls it with `{}` even when
|
|
43
|
+
* the user dictated exact args (0.4.x E2E, report-mastra defect 5: the
|
|
44
|
+
* approved call then executed with an empty body). A schema with declared
|
|
45
|
+
* properties survives those transforms, so open inputs ride a single declared
|
|
46
|
+
* JSON-string property instead, unwrapped in execute before the guard.
|
|
47
|
+
*/
|
|
48
|
+
function isOpenObjectSchema(schema) {
|
|
49
|
+
if (typeof schema !== "object" || schema === null || Array.isArray(schema))
|
|
50
|
+
return false;
|
|
51
|
+
const record = schema;
|
|
52
|
+
if (record.type !== undefined && record.type !== "object")
|
|
53
|
+
return false;
|
|
54
|
+
const properties = record.properties;
|
|
55
|
+
const declared = typeof properties === "object" && properties !== null
|
|
56
|
+
&& Object.keys(properties).length > 0;
|
|
57
|
+
return !declared && record.additionalProperties !== false;
|
|
58
|
+
}
|
|
59
|
+
function openArgsBridgeSchema(tool) {
|
|
60
|
+
return {
|
|
61
|
+
type: "object",
|
|
62
|
+
properties: {
|
|
63
|
+
[OPEN_ARGS_KEY]: {
|
|
64
|
+
// Both forms validate at runtime; strict-mode providers ride the
|
|
65
|
+
// string branch (their compat layer closes every object node), and
|
|
66
|
+
// permissive providers may pass the object directly.
|
|
67
|
+
type: ["string", "object"],
|
|
68
|
+
description: `The arguments to pass to ${tool}: a JSON object, or that object encoded as one JSON string literal (e.g. {"field":"value"}). Include every field the request calls for; pass {} when there are none.`,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/** Recover the real tool args from a bridged call: a JSON-string `args`
|
|
74
|
+
* (the advertised shape), a plain-object `args` (a model that skipped the
|
|
75
|
+
* encoding), or the raw payload itself (a provider that ignored the bridge). */
|
|
76
|
+
function unwrapOpenArgs(input) {
|
|
77
|
+
if (typeof input !== "object" || input === null || Array.isArray(input))
|
|
78
|
+
return input ?? {};
|
|
79
|
+
const record = input;
|
|
80
|
+
if (OPEN_ARGS_KEY in record) {
|
|
81
|
+
const value = record[OPEN_ARGS_KEY];
|
|
82
|
+
if (value === null || value === undefined)
|
|
83
|
+
return {};
|
|
84
|
+
if (typeof value === "string") {
|
|
85
|
+
const trimmed = value.trim();
|
|
86
|
+
if (trimmed === "")
|
|
87
|
+
return {};
|
|
88
|
+
try {
|
|
89
|
+
return JSON.parse(trimmed);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
throw new VendoError("validation", `${OPEN_ARGS_KEY} must be one JSON object literal (e.g. {"field":"value"}); the provided value did not parse as JSON`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (typeof value === "object" && !Array.isArray(value))
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
return record;
|
|
99
|
+
}
|
|
32
100
|
function principalFrom(context) {
|
|
33
101
|
const candidate = context?.requestContext?.get(VENDO_PRINCIPAL_KEY);
|
|
34
102
|
if (typeof candidate?.kind !== "string" || typeof candidate.subject !== "string") {
|
|
@@ -74,11 +142,12 @@ export async function vendoMastraTools(vendo, options) {
|
|
|
74
142
|
});
|
|
75
143
|
const tools = {};
|
|
76
144
|
for (const entry of pack) {
|
|
145
|
+
const bridged = isOpenObjectSchema(entry.inputSchema);
|
|
77
146
|
tools[entry.name] = createTool({
|
|
78
147
|
id: entry.name,
|
|
79
148
|
description: entry.description,
|
|
80
|
-
inputSchema: entry.inputSchema,
|
|
81
|
-
execute: (inputData, context) => entry.execute(inputData, {
|
|
149
|
+
inputSchema: bridged ? openArgsBridgeSchema(entry.name) : entry.inputSchema,
|
|
150
|
+
execute: (inputData, context) => entry.execute(bridged ? unwrapOpenArgs(inputData) : inputData, {
|
|
82
151
|
ctx: runContextFrom(context),
|
|
83
152
|
...(context?.agent?.toolCallId === undefined ? {} : { callId: context.agent.toolCallId }),
|
|
84
153
|
}),
|
package/dist/react.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { VendoProvider } from "@vendoai/ui";
|
|
2
2
|
import { type ComponentProps } from "react";
|
|
3
3
|
export { createVendoClient, type VendoClient, type VendoClientConfig, VendoProvider, hostComponentMap, useVendoContext, useVendoDiscoverability, useVendoGreeting, useVendoTheme, useVendoTools, type ConnectorOption, type HostComponentsInput, defaultVendoGreeting, type VendoDiscoverability, type VendoGreeting, type ToolMeta, type ToolMetaMap, VendoAppEmbed, VendoApprovalEmbed, VendoToolResult, useActivity, useApp, useApps, useApprovals, useAutomations, useConnections, useConnectorCatalog, useGrants, useMobileTakeover, type MobileTakeover, type PollOptions, useSlotApp, useThreads, useVendoOverlay, type VendoOverlayController, useVendoStatus, useVendoThread, type VendoThreadApproval, ScriptedTransport, type DirectorCue, type DirectorScript, defaultVendoTheme, resolveTheme, themeCssVariables, useVoice, type UseVoiceResult, type OpenSurface, type InClientVenue, type PinDrift, type ShipDiff, type EditResult, type PinRebaseResult, type VersionEntry, type ConnectionAccount, type InitiatedConnection, type RunStatus, type RunRecord, type RunPlan, type AutomationEntry, type EnableResult, type Thread, type ThreadSummary, type GuardPosture, type VendoStatus, } from "@vendoai/ui";
|
|
4
|
+
export { VendoOverlay, type VendoOverlayProps } from "@vendoai/ui/chrome";
|
|
4
5
|
export { remixable, type RemixableRegistration, type RemixableReportOptions } from "./remixable.js";
|
|
5
6
|
type ProviderProps = ComponentProps<typeof VendoProvider>;
|
|
6
7
|
/** 09-vendo §1 — the UI provider prewired to the default wire base. */
|
package/dist/react.js
CHANGED
|
@@ -23,6 +23,13 @@ useActivity, useApp, useApps, useApprovals, useAutomations, useConnections, useC
|
|
|
23
23
|
defaultVendoTheme, resolveTheme, themeCssVariables,
|
|
24
24
|
// voice/use-voice.ts
|
|
25
25
|
useVoice, } from "@vendoai/ui";
|
|
26
|
+
// The visible agent surface (launcher pill + panel) — re-exported from the
|
|
27
|
+
// chrome subpath so the init-scaffolded layout wrapper can import everything
|
|
28
|
+
// from "@vendoai/vendo/react": hosts only get @vendoai/vendo as a direct
|
|
29
|
+
// dependency, and under pnpm strict linking the transitive "@vendoai/ui/chrome"
|
|
30
|
+
// does not resolve for them (same TS2307 story as the registry's
|
|
31
|
+
// ComponentRegistry import).
|
|
32
|
+
export { VendoOverlay } from "@vendoai/ui/chrome";
|
|
26
33
|
export { remixable } from "./remixable.js";
|
|
27
34
|
/** 09-vendo §1 — the UI provider prewired to the default wire base. */
|
|
28
35
|
export function VendoRoot(props) {
|
package/dist/refine.js
CHANGED
|
@@ -4,6 +4,7 @@ import { validateCapabilities, capabilitiesFileSchema, overridesFileSchema, tool
|
|
|
4
4
|
import { TOOL_NAME_PATTERN, VENDO_CAPABILITIES_FORMAT, VENDO_OVERRIDES_FORMAT, capabilityMissEventSchema, } from "@vendoai/core";
|
|
5
5
|
import { generateObject } from "ai";
|
|
6
6
|
import { z } from "zod";
|
|
7
|
+
import { defaultFetch } from "@vendoai/core";
|
|
7
8
|
/**
|
|
8
9
|
* The refine engine (ENG-250, extraction spec §3). One engine, two surfaces:
|
|
9
10
|
* the `vendo refine` CLI command and the end-of-init offer — both call
|
|
@@ -496,7 +497,7 @@ const stringify = (value) => `${JSON.stringify(value, null, 2)}\n`;
|
|
|
496
497
|
// ---------------------------------------------------------------------------
|
|
497
498
|
export async function runRefine(options) {
|
|
498
499
|
const root = resolve(options.root);
|
|
499
|
-
const fetchImpl = options.fetchImpl ??
|
|
500
|
+
const fetchImpl = options.fetchImpl ?? defaultFetch;
|
|
500
501
|
const interview = options.interview ?? [];
|
|
501
502
|
const startedAt = new Date().toISOString();
|
|
502
503
|
const inputs = await loadInputs(root, options);
|
package/dist/sandbox.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { VendoError } from "@vendoai/core";
|
|
1
|
+
import { defaultFetch, VendoError } from "@vendoai/core";
|
|
2
2
|
import { deploymentIdentityHeaders } from "./deployment-identity.js";
|
|
3
3
|
import { CLOUD_BOX_PORT, CLOUD_SANDBOX_PATH, CLOUD_SNAPSHOT_REF_PREFIX, CLOUD_SNAPSHOTS_SUBPATH, CONSOLE_SNAPSHOT_REF_PREFIX, } from "./sandbox-wire.js";
|
|
4
4
|
/** Console error codes forwarded as-is when they are wire-legal VendoError
|
|
@@ -142,7 +142,7 @@ const isGone = (error) => error instanceof VendoError && error.code === "not-fou
|
|
|
142
142
|
export function cloudSandbox(options) {
|
|
143
143
|
const base = (options.baseUrl ?? "https://console.vendo.run").replace(/\/$/, "");
|
|
144
144
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
145
|
-
const fetchImpl = options.fetch ??
|
|
145
|
+
const fetchImpl = options.fetch ?? defaultFetch;
|
|
146
146
|
const send = async (path, init = {}) => {
|
|
147
147
|
const response = await fetchImpl(`${base}${CLOUD_SANDBOX_PATH}${path}`, {
|
|
148
148
|
...init,
|
package/dist/server.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { createStore, envSecrets, secretStore, storeSecrets } from "@vendoai/sto
|
|
|
11
11
|
export { hostAuthPresetConformance, type HostAuthPreset, type HostAuthPresetConformanceOptions, type HostAuthPresetOptions, type HostAuthPresetUser, type HostAuthPresetUserResolver, type SupabaseHostAuthPresetOptions, } from "./auth-presets/index.js";
|
|
12
12
|
import type { HostAuthPreset } from "./auth-presets/index.js";
|
|
13
13
|
import type { LanguageModel } from "ai";
|
|
14
|
-
export { devModel, type DevModelOptions } from "
|
|
14
|
+
export { devModel, type DevModelOptions } from "#dev-creds/model";
|
|
15
15
|
import { type ConnectionsService } from "./connections.js";
|
|
16
16
|
export { byoConnections, cloudConnections, unconfiguredConnections, type CloudConnectionsOptions, type ConnectionsService, } from "./connections.js";
|
|
17
17
|
export { cloudSandbox, type CloudSandboxOptions } from "./sandbox.js";
|
package/dist/server.js
CHANGED
|
@@ -28,11 +28,11 @@ import { createByoApprovals } from "./byo-approvals.js";
|
|
|
28
28
|
import { initTelemetry } from "@vendoai/telemetry";
|
|
29
29
|
import { capabilitySurfaceSnapshot, createCapabilityMissCapture, } from "./capability-misses.js";
|
|
30
30
|
import { catalogThemeSummary, mergeRuntimeCatalog, normalizeCatalogConfig, runtimeCatalogFromJson } from "./catalog.js";
|
|
31
|
-
import { devModel } from "
|
|
31
|
+
import { devModel } from "#dev-creds/model";
|
|
32
32
|
// install-dx v1 — `devModel()` is the env-resolving model createVendo composes
|
|
33
33
|
// when the host passes none; the resolver is shared by init and doctor (one
|
|
34
34
|
// credential story, real keys only).
|
|
35
|
-
export { devModel } from "
|
|
35
|
+
export { devModel } from "#dev-creds/model";
|
|
36
36
|
import { byoConnections, cloudConnections, hasConnections, unconfiguredConnections, } from "./connections.js";
|
|
37
37
|
// The shipped connections adapters ride the server surface so a host can pass
|
|
38
38
|
// one explicitly via createVendo({ connections }) — see selectConnections.
|
|
@@ -594,7 +594,7 @@ function createWireHandler(deps) {
|
|
|
594
594
|
// addressing a real Vendo WIRE route may (04 §4), and the door's paths are
|
|
595
595
|
// the door's, not wire routes.
|
|
596
596
|
if (deps.door !== undefined && isDoorPath(url.pathname)) {
|
|
597
|
-
await deps.ready;
|
|
597
|
+
await deps.ready();
|
|
598
598
|
return await deps.door.handler(request);
|
|
599
599
|
}
|
|
600
600
|
const path = relativePath(url);
|
|
@@ -606,7 +606,7 @@ function createWireHandler(deps) {
|
|
|
606
606
|
if (jsonMutationRequired(request, path) && !isJsonRequest(request)) {
|
|
607
607
|
throw new VendoError("validation", "content-type must be application/json");
|
|
608
608
|
}
|
|
609
|
-
await deps.ready;
|
|
609
|
+
await deps.ready();
|
|
610
610
|
// The per-request view the route table dispatches on (kill-list B4).
|
|
611
611
|
// Segments decode lazily so raw-matched pre-routes (proxy, webhooks,
|
|
612
612
|
// doctor) never decode — preserving the old chain's decode timing.
|
|
@@ -688,10 +688,23 @@ export function createVendo(config) {
|
|
|
688
688
|
// Inference, selected by the adapter rule at this composition seam
|
|
689
689
|
// (selectModel above) — the one model the agent and apps blocks consume.
|
|
690
690
|
const inference = selectModel(config.model);
|
|
691
|
-
|
|
692
|
-
//
|
|
693
|
-
//
|
|
694
|
-
|
|
691
|
+
// Construction stays PURE — no I/O, no timers — because the common edge
|
|
692
|
+
// wiring calls createVendo() at module init, where Workers forbids both
|
|
693
|
+
// (Mohamed's field report: "Disallowed operation called within global
|
|
694
|
+
// scope"). The first handler/emit touch starts schema readiness and the
|
|
695
|
+
// background sweep together through this once-latch; on Node the first
|
|
696
|
+
// request pays the same cost the old eager kick merely front-loaded.
|
|
697
|
+
let startBackgroundSweep = () => undefined;
|
|
698
|
+
let readyState;
|
|
699
|
+
const ready = () => {
|
|
700
|
+
if (readyState === undefined) {
|
|
701
|
+
readyState = store.ensureSchema();
|
|
702
|
+
// No unhandled rejection before a handler/emit awaits the latch.
|
|
703
|
+
void readyState.catch(() => undefined);
|
|
704
|
+
startBackgroundSweep();
|
|
705
|
+
}
|
|
706
|
+
return readyState;
|
|
707
|
+
};
|
|
695
708
|
let resolveAppToolRisk;
|
|
696
709
|
const guard = createGuard({
|
|
697
710
|
store,
|
|
@@ -1101,16 +1114,21 @@ export function createVendo(config) {
|
|
|
1101
1114
|
// engine pattern) so an idle process still reclaims sessions with no traffic;
|
|
1102
1115
|
// unref'd means it never keeps the event loop alive. Torn down with the store.
|
|
1103
1116
|
if (sweepEnabled) {
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1117
|
+
// Armed by the ready() latch above, NOT at construction: timers are
|
|
1118
|
+
// illegal in Workers global scope, and a process that never serves a
|
|
1119
|
+
// request has nothing to sweep.
|
|
1120
|
+
startBackgroundSweep = () => {
|
|
1121
|
+
const sweepTimer = setInterval(() => {
|
|
1122
|
+
runSweep().catch((error) => {
|
|
1123
|
+
console.warn(`[vendo] session sweep failed; will retry next interval: ${error instanceof Error ? error.message : String(error)}`);
|
|
1124
|
+
});
|
|
1125
|
+
}, sessionsConfig.sweepIntervalMs);
|
|
1126
|
+
sweepTimer.unref?.();
|
|
1127
|
+
const closeStore = store.close.bind(store);
|
|
1128
|
+
store.close = async () => {
|
|
1129
|
+
clearInterval(sweepTimer);
|
|
1130
|
+
await closeStore();
|
|
1131
|
+
};
|
|
1114
1132
|
};
|
|
1115
1133
|
}
|
|
1116
1134
|
// Wave 2 (Cloud auto): a keyed deployment's schedule- and external-triggered
|
|
@@ -1196,7 +1214,11 @@ export function createVendo(config) {
|
|
|
1196
1214
|
...(theme === undefined ? {} : { theme }),
|
|
1197
1215
|
});
|
|
1198
1216
|
}
|
|
1199
|
-
|
|
1217
|
+
// Minted on first request via the deps getter below — Workers forbids
|
|
1218
|
+
// generating random values in global scope, and createVendo runs at module
|
|
1219
|
+
// init in the edge wiring. Still one fallback id per process.
|
|
1220
|
+
let processSessionId;
|
|
1221
|
+
const sessionId = () => (processSessionId ??= `session_${globalThis.crypto.randomUUID()}`);
|
|
1200
1222
|
// Anonymous principals are minted per-CLIENT in the handler (opaque cookie
|
|
1201
1223
|
// pointer; the store's vendo_sessions row is the authority — kill-list B3).
|
|
1202
1224
|
// An https VENDO_BASE_URL means TLS terminates at a trusted proxy and requests
|
|
@@ -1220,7 +1242,7 @@ export function createVendo(config) {
|
|
|
1220
1242
|
principal: resolvePrincipal,
|
|
1221
1243
|
ready,
|
|
1222
1244
|
trustedBaseIsHttps,
|
|
1223
|
-
sessionId,
|
|
1245
|
+
get sessionId() { return sessionId(); },
|
|
1224
1246
|
store,
|
|
1225
1247
|
telemetry: telemetryClient(config.telemetry),
|
|
1226
1248
|
agent,
|
|
@@ -1267,12 +1289,24 @@ export function createVendo(config) {
|
|
|
1267
1289
|
return {
|
|
1268
1290
|
handler,
|
|
1269
1291
|
async emit(event, payload, principal) {
|
|
1270
|
-
await ready;
|
|
1292
|
+
await ready();
|
|
1271
1293
|
return automations.emit(event, payload, principal);
|
|
1272
1294
|
},
|
|
1273
1295
|
agent,
|
|
1274
1296
|
guard,
|
|
1275
|
-
|
|
1297
|
+
// The BYO seam (ai-sdk.ts / mastra.ts tool packs) reaches the store
|
|
1298
|
+
// without ever touching handler/emit, so its execute leg arms the same
|
|
1299
|
+
// ready() latch — the composed-block head start the old eager kick gave
|
|
1300
|
+
// such hosts, without the construction-time I/O Workers forbids. Direct
|
|
1301
|
+
// vendo.store/automations reach-ins still own their readiness (await
|
|
1302
|
+
// store.ensureSchema(), as the mastra example and defer tests do).
|
|
1303
|
+
guardedTools: {
|
|
1304
|
+
...byoApprovals.registry,
|
|
1305
|
+
execute: async (call, ctx) => {
|
|
1306
|
+
await ready();
|
|
1307
|
+
return byoApprovals.registry.execute(call, ctx);
|
|
1308
|
+
},
|
|
1309
|
+
},
|
|
1276
1310
|
apps,
|
|
1277
1311
|
automations,
|
|
1278
1312
|
actions,
|
package/dist/wire/apps.js
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
import { VendoError } from "@vendoai/core";
|
|
2
|
+
import { appStore } from "@vendoai/store";
|
|
2
3
|
import { json, requestJson, route, string } from "./shared.js";
|
|
4
|
+
/** Unscoped existence probe behind the ?pending=1 disambiguation: does ANY
|
|
5
|
+
principal own a record with this id? Owner-scoped open() answers not-found
|
|
6
|
+
for both "still building" and "exists under someone else", and masking the
|
|
7
|
+
latter as pending is the infinite skeleton of 0.4.1 E2E cert B4 (wire
|
|
8
|
+
principal ≠ chat principal). No document content leaves this check. A
|
|
9
|
+
store that can't answer (hosted wire-door stores have no local db handle)
|
|
10
|
+
keeps the pending window — today's behavior. */
|
|
11
|
+
async function appRecordExists(store, appId) {
|
|
12
|
+
try {
|
|
13
|
+
return (await appStore(store).get(appId)) !== null;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
3
19
|
/** 06-apps / 09 §3 — the /apps wire area: CRUD, open/call/edit, history,
|
|
4
20
|
ship-diff, pin drift/rebase, the gesture fork (fork-pin), export/import,
|
|
5
21
|
fork (whole-app copy — a different feature from fork-pin). */
|
|
@@ -71,13 +87,26 @@ export const appRoutes = [
|
|
|
71
87
|
// console 404. Under the additive ?pending=1 flag, ONLY that expected
|
|
72
88
|
// pre-servable miss becomes a quiet 200 {kind:"pending"}; unflagged
|
|
73
89
|
// callers keep the contracted 404, and every other failure keeps its
|
|
74
|
-
// envelope and status either way.
|
|
90
|
+
// envelope and status either way. A record that DOES exist — just not
|
|
91
|
+
// for this caller — is not a build in progress and never will be: that
|
|
92
|
+
// answers the terminal failed vocabulary (with the principal-mismatch
|
|
93
|
+
// diagnosis) so the embed resolves promptly instead of skeleton-polling
|
|
94
|
+
// to its deadline (0.4.1 E2E cert B4).
|
|
75
95
|
if (wire.url.searchParams.get("pending") === "1") {
|
|
76
96
|
try {
|
|
77
97
|
return json(await deps.apps.open(appId, ctx));
|
|
78
98
|
}
|
|
79
99
|
catch (reason) {
|
|
80
100
|
if (reason instanceof VendoError && reason.code === "not-found") {
|
|
101
|
+
if (await appRecordExists(deps.store, appId)) {
|
|
102
|
+
return json({
|
|
103
|
+
kind: "failed",
|
|
104
|
+
reason: "this app exists but is not visible to this surface's caller — "
|
|
105
|
+
+ "the wire route's principal must resolve the same subject your agent loop uses "
|
|
106
|
+
+ "(see the principal comment in the generated route, or docs.vendo.run/existing-agents)",
|
|
107
|
+
retryable: false,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
81
110
|
return json({ kind: "pending" });
|
|
82
111
|
}
|
|
83
112
|
throw reason;
|
package/dist/wire/shared.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ import type { RuntimeCaptureHandler } from "../runtime-capture.js";
|
|
|
14
14
|
shares. The anonymous-session + RunContext resolution lives in
|
|
15
15
|
wire/context.ts; server.ts assembles the table from the per-area modules
|
|
16
16
|
under src/wire/. */
|
|
17
|
-
export declare const VERSION = "0.4.
|
|
17
|
+
export declare const VERSION = "0.4.4";
|
|
18
18
|
export declare const BASE_PATH = "/api/vendo";
|
|
19
19
|
export type SandboxVenue = "e2b" | "cloud" | "custom" | false;
|
|
20
20
|
/** How inference is served: "custom" (a host-passed model) or "ladder" (the
|
|
@@ -24,7 +24,7 @@ export type SandboxVenue = "e2b" | "cloud" | "custom" | false;
|
|
|
24
24
|
export type ModelVenue = "custom" | "ladder";
|
|
25
25
|
export interface WireDeps {
|
|
26
26
|
principal: (req: Request) => Promise<Principal | null>;
|
|
27
|
-
ready: Promise<void>;
|
|
27
|
+
ready: () => Promise<void>;
|
|
28
28
|
/** VENDO_BASE_URL is https → TLS terminates upstream; see secureRequest. */
|
|
29
29
|
trustedBaseIsHttps: boolean;
|
|
30
30
|
sessionId: string;
|
package/dist/wire/shared.js
CHANGED
|
@@ -4,7 +4,7 @@ import { VendoError, } from "@vendoai/core";
|
|
|
4
4
|
shares. The anonymous-session + RunContext resolution lives in
|
|
5
5
|
wire/context.ts; server.ts assembles the table from the per-area modules
|
|
6
6
|
under src/wire/. */
|
|
7
|
-
export const VERSION = "0.4.
|
|
7
|
+
export const VERSION = "0.4.4";
|
|
8
8
|
export const BASE_PATH = "/api/vendo";
|
|
9
9
|
const STATUS_BY_CODE = {
|
|
10
10
|
validation: 400,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vendoai/vendo",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "The Vendo umbrella: default composition, public wire routes, React provider, and the vendo CLI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -86,16 +86,16 @@
|
|
|
86
86
|
"ajv": "^8.20.0",
|
|
87
87
|
"ajv-formats": "^3.0.1",
|
|
88
88
|
"zod": "^3.25.0",
|
|
89
|
-
"@vendoai/actions": "0.4.
|
|
90
|
-
"@vendoai/
|
|
91
|
-
"@vendoai/
|
|
92
|
-
"@vendoai/
|
|
93
|
-
"@vendoai/core": "0.4.
|
|
94
|
-
"@vendoai/guard": "0.4.
|
|
95
|
-
"@vendoai/mcp": "0.4.
|
|
96
|
-
"@vendoai/store": "0.4.
|
|
97
|
-
"@vendoai/
|
|
98
|
-
"@vendoai/
|
|
89
|
+
"@vendoai/actions": "0.4.4",
|
|
90
|
+
"@vendoai/agent": "0.4.4",
|
|
91
|
+
"@vendoai/apps": "0.4.4",
|
|
92
|
+
"@vendoai/automations": "0.4.4",
|
|
93
|
+
"@vendoai/core": "0.4.4",
|
|
94
|
+
"@vendoai/guard": "0.4.4",
|
|
95
|
+
"@vendoai/mcp": "0.4.4",
|
|
96
|
+
"@vendoai/store": "0.4.4",
|
|
97
|
+
"@vendoai/ui": "0.4.4",
|
|
98
|
+
"@vendoai/telemetry": "0.3.2"
|
|
99
99
|
},
|
|
100
100
|
"peerDependencies": {
|
|
101
101
|
"@auth/core": "^0.34.3",
|
|
@@ -137,6 +137,15 @@
|
|
|
137
137
|
"vite": "^6.0.0",
|
|
138
138
|
"vitest": "^2.1.0"
|
|
139
139
|
},
|
|
140
|
+
"imports": {
|
|
141
|
+
"#dev-creds/model": {
|
|
142
|
+
"workerd": "./dist/dev-creds/model-edge.js",
|
|
143
|
+
"worker": "./dist/dev-creds/model-edge.js",
|
|
144
|
+
"edge-light": "./dist/dev-creds/model-edge.js",
|
|
145
|
+
"browser": "./dist/dev-creds/model-edge.js",
|
|
146
|
+
"default": "./dist/dev-creds/model.js"
|
|
147
|
+
}
|
|
148
|
+
},
|
|
140
149
|
"scripts": {
|
|
141
150
|
"build:playground": "node scripts/build-playground.mjs",
|
|
142
151
|
"prebuild": "pnpm run build:playground",
|