@vendoai/vendo 0.4.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/LICENSE +202 -0
- package/README.md +28 -0
- package/bin/vendo.mjs +4 -0
- package/dist/ai-sdk.d.ts +35 -0
- package/dist/ai-sdk.js +62 -0
- package/dist/auth-presets/auth-js.d.ts +14 -0
- package/dist/auth-presets/auth-js.js +91 -0
- package/dist/auth-presets/auth0.d.ts +23 -0
- package/dist/auth-presets/auth0.js +98 -0
- package/dist/auth-presets/clerk.d.ts +23 -0
- package/dist/auth-presets/clerk.js +65 -0
- package/dist/auth-presets/conformance.d.ts +42 -0
- package/dist/auth-presets/conformance.js +139 -0
- package/dist/auth-presets/identity.d.ts +56 -0
- package/dist/auth-presets/identity.js +152 -0
- package/dist/auth-presets/index.d.ts +14 -0
- package/dist/auth-presets/index.js +12 -0
- package/dist/auth-presets/jwt.d.ts +16 -0
- package/dist/auth-presets/jwt.js +54 -0
- package/dist/auth-presets/shared.d.ts +35 -0
- package/dist/auth-presets/shared.js +1 -0
- package/dist/auth-presets/supabase.d.ts +42 -0
- package/dist/auth-presets/supabase.js +229 -0
- package/dist/byo-approvals.d.ts +37 -0
- package/dist/byo-approvals.js +189 -0
- package/dist/capability-misses.d.ts +38 -0
- package/dist/capability-misses.js +172 -0
- package/dist/catalog.d.ts +19 -0
- package/dist/catalog.js +152 -0
- package/dist/cli/cloud/args.d.ts +3 -0
- package/dist/cli/cloud/args.js +32 -0
- package/dist/cli/cloud/auth.d.ts +17 -0
- package/dist/cli/cloud/auth.js +123 -0
- package/dist/cli/cloud/client.d.ts +28 -0
- package/dist/cli/cloud/client.js +133 -0
- package/dist/cli/cloud/command.d.ts +22 -0
- package/dist/cli/cloud/command.js +73 -0
- package/dist/cli/cloud/deploy.d.ts +26 -0
- package/dist/cli/cloud/deploy.js +187 -0
- package/dist/cli/cloud/device-login.d.ts +32 -0
- package/dist/cli/cloud/device-login.js +259 -0
- package/dist/cli/cloud/index.d.ts +5 -0
- package/dist/cli/cloud/index.js +59 -0
- package/dist/cli/cloud/keys.d.ts +2 -0
- package/dist/cli/cloud/keys.js +31 -0
- package/dist/cli/cloud/members.d.ts +3 -0
- package/dist/cli/cloud/members.js +25 -0
- package/dist/cli/cloud/output.d.ts +4 -0
- package/dist/cli/cloud/output.js +12 -0
- package/dist/cli/cloud/pending-claim.d.ts +29 -0
- package/dist/cli/cloud/pending-claim.js +38 -0
- package/dist/cli/cloud/read.d.ts +3 -0
- package/dist/cli/cloud/read.js +12 -0
- package/dist/cli/cloud/services.d.ts +2 -0
- package/dist/cli/cloud/services.js +9 -0
- package/dist/cli/cloud/session.d.ts +13 -0
- package/dist/cli/cloud/session.js +41 -0
- package/dist/cli/cloud-init.d.ts +60 -0
- package/dist/cli/cloud-init.js +149 -0
- package/dist/cli/dep-versions.d.ts +26 -0
- package/dist/cli/dep-versions.js +77 -0
- package/dist/cli/doctor-codes.d.ts +58 -0
- package/dist/cli/doctor-codes.js +60 -0
- package/dist/cli/doctor-live.d.ts +67 -0
- package/dist/cli/doctor-live.js +169 -0
- package/dist/cli/doctor.d.ts +52 -0
- package/dist/cli/doctor.js +467 -0
- package/dist/cli/eject.d.ts +29 -0
- package/dist/cli/eject.js +141 -0
- package/dist/cli/extract/apply.d.ts +26 -0
- package/dist/cli/extract/apply.js +123 -0
- package/dist/cli/extract/claude-cli-harness.d.ts +18 -0
- package/dist/cli/extract/claude-cli-harness.js +132 -0
- package/dist/cli/extract/claude-harness.d.ts +14 -0
- package/dist/cli/extract/claude-harness.js +127 -0
- package/dist/cli/extract/codex-cli-harness.d.ts +31 -0
- package/dist/cli/extract/codex-cli-harness.js +154 -0
- package/dist/cli/extract/delegate.d.ts +21 -0
- package/dist/cli/extract/delegate.js +77 -0
- package/dist/cli/extract/extraction.d.ts +65 -0
- package/dist/cli/extract/extraction.js +300 -0
- package/dist/cli/extract/gateway-fuel.d.ts +69 -0
- package/dist/cli/extract/gateway-fuel.js +69 -0
- package/dist/cli/extract/harness.d.ts +114 -0
- package/dist/cli/extract/harness.js +84 -0
- package/dist/cli/extract/index.d.ts +9 -0
- package/dist/cli/extract/index.js +9 -0
- package/dist/cli/extract/npx-engine-harness.d.ts +73 -0
- package/dist/cli/extract/npx-engine-harness.js +225 -0
- package/dist/cli/extract/stages.d.ts +149 -0
- package/dist/cli/extract/stages.js +398 -0
- package/dist/cli/framework.d.ts +8 -0
- package/dist/cli/framework.js +36 -0
- package/dist/cli/init-auth.d.ts +67 -0
- package/dist/cli/init-auth.js +142 -0
- package/dist/cli/init-scaffolds.d.ts +28 -0
- package/dist/cli/init-scaffolds.js +235 -0
- package/dist/cli/init.d.ts +115 -0
- package/dist/cli/init.js +1008 -0
- package/dist/cli/mcp/index.d.ts +7 -0
- package/dist/cli/mcp/index.js +59 -0
- package/dist/cli/mcp/registry.d.ts +9 -0
- package/dist/cli/mcp/registry.js +117 -0
- package/dist/cli/mcp/server-json.d.ts +12 -0
- package/dist/cli/mcp/server-json.js +65 -0
- package/dist/cli/mcp/server.schema.json +574 -0
- package/dist/cli/mcp/verify-domain.d.ts +11 -0
- package/dist/cli/mcp/verify-domain.js +48 -0
- package/dist/cli/playground/app/embed-entry.d.ts +20 -0
- package/dist/cli/playground/app/embed-entry.js +46 -0
- package/dist/cli/playground/app/fake-client.d.ts +3 -0
- package/dist/cli/playground/app/fake-client.js +215 -0
- package/dist/cli/playground/app/fixtures.d.ts +47 -0
- package/dist/cli/playground/app/fixtures.js +472 -0
- package/dist/cli/playground/app/main.d.ts +1 -0
- package/dist/cli/playground/app/main.js +108 -0
- package/dist/cli/playground/app/scenario-mount.d.ts +13 -0
- package/dist/cli/playground/app/scenario-mount.js +48 -0
- package/dist/cli/playground/app/scenarios.d.ts +25 -0
- package/dist/cli/playground/app/scenarios.js +152 -0
- package/dist/cli/playground/app/theme-editor.d.ts +13 -0
- package/dist/cli/playground/app/theme-editor.js +149 -0
- package/dist/cli/playground/app/theme-state.d.ts +29 -0
- package/dist/cli/playground/app/theme-state.js +151 -0
- package/dist/cli/playground/bundle.gen.d.ts +2 -0
- package/dist/cli/playground/bundle.gen.js +2 -0
- package/dist/cli/playground/embed-bundle.gen.d.ts +2 -0
- package/dist/cli/playground/embed-bundle.gen.js +2 -0
- package/dist/cli/playground.d.ts +33 -0
- package/dist/cli/playground.js +120 -0
- package/dist/cli/pretty.d.ts +48 -0
- package/dist/cli/pretty.js +330 -0
- package/dist/cli/refine.d.ts +43 -0
- package/dist/cli/refine.js +181 -0
- package/dist/cli/semantics.d.ts +31 -0
- package/dist/cli/semantics.js +122 -0
- package/dist/cli/shared.d.ts +68 -0
- package/dist/cli/shared.js +184 -0
- package/dist/cli/sync.d.ts +36 -0
- package/dist/cli/sync.js +202 -0
- package/dist/cli/theme/color.d.ts +15 -0
- package/dist/cli/theme/color.js +188 -0
- package/dist/cli/theme/css-vars.d.ts +13 -0
- package/dist/cli/theme/css-vars.js +40 -0
- package/dist/cli/theme/entry-candidates.d.ts +5 -0
- package/dist/cli/theme/entry-candidates.js +22 -0
- package/dist/cli/theme/extract-theme.d.ts +184 -0
- package/dist/cli/theme/extract-theme.js +358 -0
- package/dist/cli/theme/walk.d.ts +2 -0
- package/dist/cli/theme/walk.js +24 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +333 -0
- package/dist/cloud-apps.d.ts +17 -0
- package/dist/cloud-apps.js +46 -0
- package/dist/cloud-console.d.ts +32 -0
- package/dist/cloud-console.js +72 -0
- package/dist/cloud-tools.d.ts +23 -0
- package/dist/cloud-tools.js +196 -0
- package/dist/connections.d.ts +71 -0
- package/dist/connections.js +192 -0
- package/dist/deployment-identity.d.ts +12 -0
- package/dist/deployment-identity.js +69 -0
- package/dist/dev-creds/model.d.ts +65 -0
- package/dist/dev-creds/model.js +159 -0
- package/dist/dev-creds/resolve.d.ts +36 -0
- package/dist/dev-creds/resolve.js +57 -0
- package/dist/hosted-store.d.ts +52 -0
- package/dist/hosted-store.js +322 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +1 -0
- package/dist/mastra.d.ts +46 -0
- package/dist/mastra.js +88 -0
- package/dist/react.d.ts +10 -0
- package/dist/react.js +32 -0
- package/dist/refine.d.ts +244 -0
- package/dist/refine.js +599 -0
- package/dist/remixable.d.ts +18 -0
- package/dist/remixable.js +42 -0
- package/dist/runtime-capture.d.ts +18 -0
- package/dist/runtime-capture.js +111 -0
- package/dist/sandbox-wire.d.ts +101 -0
- package/dist/sandbox-wire.js +101 -0
- package/dist/sandbox.d.ts +38 -0
- package/dist/sandbox.js +389 -0
- package/dist/server.d.ts +216 -0
- package/dist/server.js +1320 -0
- package/dist/sync-impact.d.ts +14 -0
- package/dist/sync-impact.js +75 -0
- package/dist/turn-liveness.d.ts +33 -0
- package/dist/turn-liveness.js +105 -0
- package/dist/wire/approvals.d.ts +10 -0
- package/dist/wire/approvals.js +59 -0
- package/dist/wire/apps.d.ts +5 -0
- package/dist/wire/apps.js +155 -0
- package/dist/wire/automations.d.ts +5 -0
- package/dist/wire/automations.js +57 -0
- package/dist/wire/box.d.ts +3 -0
- package/dist/wire/box.js +268 -0
- package/dist/wire/connections.d.ts +5 -0
- package/dist/wire/connections.js +47 -0
- package/dist/wire/context.d.ts +22 -0
- package/dist/wire/context.js +190 -0
- package/dist/wire/doctor.d.ts +19 -0
- package/dist/wire/doctor.js +116 -0
- package/dist/wire/misc.d.ts +18 -0
- package/dist/wire/misc.js +227 -0
- package/dist/wire/shared.d.ts +158 -0
- package/dist/wire/shared.js +134 -0
- package/dist/wire/threads.d.ts +3 -0
- package/dist/wire/threads.js +68 -0
- package/package.json +151 -0
- package/skills/vendo-setup/SKILL.md +128 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { composioToolRisk, normalizeToolName } from "@vendoai/actions";
|
|
2
|
+
import { deploymentIdentityHeaders } from "./deployment-identity.js";
|
|
3
|
+
function errorOutcome(message) {
|
|
4
|
+
return { status: "error", error: { code: "connector-error", message } };
|
|
5
|
+
}
|
|
6
|
+
function withIdentity(outcome, identity) {
|
|
7
|
+
return Object.assign({}, outcome, { connectorAccount: identity });
|
|
8
|
+
}
|
|
9
|
+
export function cloudTools(options) {
|
|
10
|
+
const base = (options.baseUrl ?? "https://console.vendo.run").replace(/\/$/, "");
|
|
11
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
12
|
+
let normalizedToRaw = new Map();
|
|
13
|
+
async function cloudFetch(path, init) {
|
|
14
|
+
const response = await fetchImpl(`${base}${path}`, {
|
|
15
|
+
...init,
|
|
16
|
+
headers: {
|
|
17
|
+
authorization: `Bearer ${options.apiKey}`,
|
|
18
|
+
accept: "application/json",
|
|
19
|
+
...(await deploymentIdentityHeaders()),
|
|
20
|
+
...(init?.body === undefined ? {} : { "content-type": "application/json" }),
|
|
21
|
+
...init?.headers,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
let payload = {};
|
|
25
|
+
try {
|
|
26
|
+
payload = await response.json();
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Non-JSON bodies fall through to the caller's status handling.
|
|
30
|
+
}
|
|
31
|
+
return { ok: response.ok, status: response.status, payload };
|
|
32
|
+
}
|
|
33
|
+
// Connection-scoped tool loading (spec 2026-07-20): without explicit `apps`
|
|
34
|
+
// the connector is LAZY — nothing fetches eagerly; discovery rides the
|
|
35
|
+
// console catalog and schemas load per toolkit on expansion.
|
|
36
|
+
const lazy = options.apps === undefined;
|
|
37
|
+
const expandedToolkits = new Set();
|
|
38
|
+
const toolkitToolCache = new Map();
|
|
39
|
+
let indexPromise;
|
|
40
|
+
/** One toolkits= fetch, degrade-never-throw (a failed toolkit just loads
|
|
41
|
+
* nothing this round; the memo is dropped so a later read retries). */
|
|
42
|
+
function fetchToolkitTools(toolkits) {
|
|
43
|
+
let promise = toolkitToolCache.get(toolkits);
|
|
44
|
+
if (!promise) {
|
|
45
|
+
promise = (async () => {
|
|
46
|
+
let response;
|
|
47
|
+
try {
|
|
48
|
+
response = await cloudFetch(`/api/v1/tools?toolkits=${encodeURIComponent(toolkits)}`);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
toolkitToolCache.delete(toolkits);
|
|
52
|
+
console.warn("[vendo] Vendo Cloud tools broker unreachable; no connector tools loaded:", error instanceof Error ? error.message : error);
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
toolkitToolCache.delete(toolkits);
|
|
57
|
+
const message = response.payload.error?.message;
|
|
58
|
+
console.warn(`[vendo] Vendo Cloud tools broker returned ${response.status}; no connector tools loaded${typeof message === "string" && message ? `: ${message}` : "."}`);
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
const items = response.payload && typeof response.payload === "object"
|
|
62
|
+
? response.payload.tools
|
|
63
|
+
: undefined;
|
|
64
|
+
return (Array.isArray(items) ? items : []);
|
|
65
|
+
})();
|
|
66
|
+
toolkitToolCache.set(toolkits, promise);
|
|
67
|
+
}
|
|
68
|
+
return promise;
|
|
69
|
+
}
|
|
70
|
+
async function buildIndex() {
|
|
71
|
+
let response;
|
|
72
|
+
try {
|
|
73
|
+
response = await cloudFetch("/api/v1/connections/catalog");
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
indexPromise = undefined;
|
|
77
|
+
console.warn("[vendo] Vendo Cloud catalog unreachable; connector discovery is empty:", error instanceof Error ? error.message : error);
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
indexPromise = undefined;
|
|
82
|
+
console.warn(`[vendo] Vendo Cloud catalog returned ${response.status}; connector discovery is empty.`);
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
const available = response.payload && typeof response.payload === "object"
|
|
86
|
+
? response.payload.available
|
|
87
|
+
: undefined;
|
|
88
|
+
if (!Array.isArray(available))
|
|
89
|
+
return [];
|
|
90
|
+
return available
|
|
91
|
+
.filter((entry) => !!entry && typeof entry === "object" && typeof entry.toolkit === "string")
|
|
92
|
+
.map((entry) => ({
|
|
93
|
+
toolkit: entry.toolkit,
|
|
94
|
+
...(typeof entry.label === "string" ? { label: entry.label } : {}),
|
|
95
|
+
...(typeof entry.description === "string" ? { description: entry.description } : {}),
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
name: "composio",
|
|
100
|
+
discoveryIndex: () => (indexPromise ??= buildIndex()),
|
|
101
|
+
async expandToolkits(toolkits) {
|
|
102
|
+
if (!lazy)
|
|
103
|
+
return false;
|
|
104
|
+
const connectable = new Set((await (indexPromise ??= buildIndex())).map((entry) => entry.toolkit));
|
|
105
|
+
let changed = false;
|
|
106
|
+
for (const toolkit of toolkits) {
|
|
107
|
+
if (!connectable.has(toolkit) || expandedToolkits.has(toolkit))
|
|
108
|
+
continue;
|
|
109
|
+
expandedToolkits.add(toolkit);
|
|
110
|
+
changed = true;
|
|
111
|
+
}
|
|
112
|
+
return changed;
|
|
113
|
+
},
|
|
114
|
+
async descriptors() {
|
|
115
|
+
// The auto-composed cloud default must never brick the host: a thrown
|
|
116
|
+
// descriptors() fails the ENTIRE registry load, host tools included.
|
|
117
|
+
// Every fetch below degrades to "no connector tools" with one warn.
|
|
118
|
+
let items;
|
|
119
|
+
if (lazy) {
|
|
120
|
+
if (expandedToolkits.size === 0) {
|
|
121
|
+
normalizedToRaw = new Map();
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
const lists = await Promise.all([...expandedToolkits].map((toolkit) => fetchToolkitTools(toolkit)));
|
|
125
|
+
items = lists.flat();
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
items = await fetchToolkitTools(options.apps.join(","));
|
|
129
|
+
}
|
|
130
|
+
const nextNormalizedToRaw = new Map();
|
|
131
|
+
const descriptors = [];
|
|
132
|
+
for (const item of items) {
|
|
133
|
+
if (typeof item.slug !== "string" || typeof item.toolkit !== "string")
|
|
134
|
+
continue;
|
|
135
|
+
const name = normalizeToolName(item.toolkit, item.slug);
|
|
136
|
+
if (nextNormalizedToRaw.has(name))
|
|
137
|
+
throw new Error(`Cloud tools name collision: ${name}`);
|
|
138
|
+
nextNormalizedToRaw.set(name, { raw: item.slug, toolkit: item.toolkit });
|
|
139
|
+
const tags = Array.isArray(item.tags)
|
|
140
|
+
? item.tags.filter((tag) => typeof tag === "string")
|
|
141
|
+
: undefined;
|
|
142
|
+
descriptors.push({
|
|
143
|
+
name,
|
|
144
|
+
description: typeof item.description === "string" ? item.description : item.slug,
|
|
145
|
+
inputSchema: item.inputParameters && typeof item.inputParameters === "object" && !Array.isArray(item.inputParameters)
|
|
146
|
+
? item.inputParameters
|
|
147
|
+
: {},
|
|
148
|
+
// The same curated risk labels BYO Composio tools get — the guard
|
|
149
|
+
// and approval cards behave identically across postures.
|
|
150
|
+
risk: composioToolRisk(item.slug, item.toolkit, tags),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Swapped atomically so a concurrent execute() never sees a half map.
|
|
154
|
+
normalizedToRaw = nextNormalizedToRaw;
|
|
155
|
+
return descriptors;
|
|
156
|
+
},
|
|
157
|
+
async execute(call, ctx) {
|
|
158
|
+
const entry = normalizedToRaw.get(call.tool);
|
|
159
|
+
if (!entry) {
|
|
160
|
+
return { status: "error", error: { code: "not-found", message: `Unknown cloud tool: ${call.tool}` } };
|
|
161
|
+
}
|
|
162
|
+
const subject = ctx.principal.subject;
|
|
163
|
+
const identity = {
|
|
164
|
+
connector: "composio",
|
|
165
|
+
toolkit: entry.toolkit,
|
|
166
|
+
entityId: subject,
|
|
167
|
+
credential: "per-principal",
|
|
168
|
+
};
|
|
169
|
+
try {
|
|
170
|
+
const response = await cloudFetch("/api/v1/tools/execute", {
|
|
171
|
+
method: "POST",
|
|
172
|
+
body: JSON.stringify({
|
|
173
|
+
subject,
|
|
174
|
+
toolkit: entry.toolkit,
|
|
175
|
+
tool: entry.raw,
|
|
176
|
+
arguments: call.args,
|
|
177
|
+
}),
|
|
178
|
+
});
|
|
179
|
+
if (!response.ok) {
|
|
180
|
+
const message = response.payload.error?.message;
|
|
181
|
+
return withIdentity(errorOutcome(typeof message === "string" && message
|
|
182
|
+
? message
|
|
183
|
+
: `Vendo Cloud tool execution failed with ${response.status}`), identity);
|
|
184
|
+
}
|
|
185
|
+
const outcome = response.payload.outcome;
|
|
186
|
+
if (!outcome || typeof outcome !== "object") {
|
|
187
|
+
return withIdentity(errorOutcome("Vendo Cloud tool execution returned no outcome"), identity);
|
|
188
|
+
}
|
|
189
|
+
return withIdentity(outcome, identity);
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
return withIdentity(errorOutcome(error instanceof Error ? error.message : "Vendo Cloud tool execution failed"), identity);
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { type Principal } from "@vendoai/core";
|
|
2
|
+
import type { Connector, ConnectorAccount, ConnectorConnections } from "@vendoai/actions";
|
|
3
|
+
export interface InitiateOptions {
|
|
4
|
+
connector?: string;
|
|
5
|
+
toolkit: string;
|
|
6
|
+
callbackUrl?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface InitiatedConnection {
|
|
9
|
+
id: string;
|
|
10
|
+
connector: string;
|
|
11
|
+
redirectUrl: string;
|
|
12
|
+
}
|
|
13
|
+
/** One row of the connect dock's auto catalog: a toolkit a user could finish
|
|
14
|
+
* connecting, tagged with the broker that would carry it. */
|
|
15
|
+
export interface ConnectableToolkit {
|
|
16
|
+
toolkit: string;
|
|
17
|
+
connector: string;
|
|
18
|
+
label?: string;
|
|
19
|
+
/** One-line capability blurb — feeds the OSS discovery index. */
|
|
20
|
+
description?: string;
|
|
21
|
+
}
|
|
22
|
+
/** 04-actions §3 (block-actions design §B) — the umbrella's per-principal
|
|
23
|
+
* connected-accounts surface. Which implementation composes is decided at the
|
|
24
|
+
* seam, never in here (adapter rule — see selectConnections in server.ts).
|
|
25
|
+
* Composio is the sole broker; two postures:
|
|
26
|
+
* - "byo": the host's own connector (its Composio key) carries connections;
|
|
27
|
+
* - "cloud": connections ride the Vendo Cloud broker endpoint using Vendo's
|
|
28
|
+
* Composio credentials — cloud users bring zero keys.
|
|
29
|
+
* Subject scoping IS the security model: every call passes exactly the
|
|
30
|
+
* resolved principal's subject; no caller-supplied subject exists on the wire. */
|
|
31
|
+
export interface ConnectionsService {
|
|
32
|
+
posture: "byo" | "cloud" | false;
|
|
33
|
+
list(principal: Principal): Promise<ConnectorAccount[]>;
|
|
34
|
+
initiate(principal: Principal, options: InitiateOptions): Promise<InitiatedConnection>;
|
|
35
|
+
status(principal: Principal, connector: string, connectionId: string): Promise<ConnectorAccount | null>;
|
|
36
|
+
disconnect(principal: Principal, connector: string, connectionId: string): Promise<void>;
|
|
37
|
+
/** The connect dock's auto catalog — host-level (every principal sees the
|
|
38
|
+
* same rows), unlike everything above. Empty when nothing is connectable. */
|
|
39
|
+
catalog(): Promise<ConnectableToolkit[]>;
|
|
40
|
+
}
|
|
41
|
+
/** The BYO capability predicate — the same test the composition seam selects
|
|
42
|
+
* on and byoConnections builds brokers from. */
|
|
43
|
+
export declare function hasConnections(connector: Connector): connector is Connector & {
|
|
44
|
+
connections: ConnectorConnections;
|
|
45
|
+
};
|
|
46
|
+
/** The BYO adapter: connections live on the host's own connector(s), because
|
|
47
|
+
* they must live where the connector executes. Built from every passed
|
|
48
|
+
* connector that carries a connections capability. */
|
|
49
|
+
export declare function byoConnections(connectors: Connector[]): ConnectionsService;
|
|
50
|
+
export interface CloudConnectionsOptions {
|
|
51
|
+
apiKey: string;
|
|
52
|
+
/** Defaults to the Vendo console; the composition seam passes VENDO_CLOUD_URL. */
|
|
53
|
+
baseUrl?: string;
|
|
54
|
+
/** Catalog scoping, mirroring cloudTools' `apps`: a host that scopes its
|
|
55
|
+
* cloud tools explicitly passes the same list here so the connect dock
|
|
56
|
+
* never advertises a toolkit the agent cannot invoke. Unset = everything
|
|
57
|
+
* the console's catalog serves. */
|
|
58
|
+
apps?: string[];
|
|
59
|
+
fetch?: typeof fetch;
|
|
60
|
+
/** Per-request abort budget (default 30s, hosted-store's) — a hung console
|
|
61
|
+
* must never wedge the connections surface. */
|
|
62
|
+
timeoutMs?: number;
|
|
63
|
+
}
|
|
64
|
+
/** The Cloud adapter — the OSS side of the zero-key cloud seam: same surface,
|
|
65
|
+
* brokered by the Vendo Cloud console (which holds Vendo's Composio
|
|
66
|
+
* credentials). The console implementation is out of scope here; this defines
|
|
67
|
+
* the wire it must serve. */
|
|
68
|
+
export declare function cloudConnections(options: CloudConnectionsOptions): ConnectionsService;
|
|
69
|
+
/** The no-broker fallback adapter: listing is honestly empty (the panel
|
|
70
|
+
* renders an empty state), any mutation explains what to configure. */
|
|
71
|
+
export declare function unconfiguredConnections(): ConnectionsService;
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { VendoError } from "@vendoai/core";
|
|
2
|
+
import { consoleSender, raiseCloudError } from "./cloud-console.js";
|
|
3
|
+
/** Subjects the runtime mints for machine principals (automations webhook
|
|
4
|
+
* triggers today; the reserved `vendo:` namespace going forward). A synthetic
|
|
5
|
+
* subject must never accrue human connected accounts — and it has no browser
|
|
6
|
+
* to complete an OAuth redirect anyway. */
|
|
7
|
+
const SYNTHETIC_SUBJECT_PREFIXES = ["webhook:", "vendo:"];
|
|
8
|
+
function guardInitiatePrincipal(principal) {
|
|
9
|
+
if (principal.ephemeral === true) {
|
|
10
|
+
throw new VendoError("blocked", "connecting external accounts requires a signed-in user; sign in first");
|
|
11
|
+
}
|
|
12
|
+
if (SYNTHETIC_SUBJECT_PREFIXES.some((prefix) => principal.subject.startsWith(prefix))) {
|
|
13
|
+
throw new VendoError("validation", "reserved synthetic subjects cannot hold connected accounts");
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function guardCallbackUrl(callbackUrl) {
|
|
17
|
+
if (callbackUrl === undefined)
|
|
18
|
+
return;
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = new URL(callbackUrl);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
throw new VendoError("validation", "callbackUrl must be an absolute http(s) URL");
|
|
25
|
+
}
|
|
26
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
27
|
+
throw new VendoError("validation", "callbackUrl must be an absolute http(s) URL");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** The BYO capability predicate — the same test the composition seam selects
|
|
31
|
+
* on and byoConnections builds brokers from. */
|
|
32
|
+
export function hasConnections(connector) {
|
|
33
|
+
return connector.connections !== undefined;
|
|
34
|
+
}
|
|
35
|
+
/** The BYO adapter: connections live on the host's own connector(s), because
|
|
36
|
+
* they must live where the connector executes. Built from every passed
|
|
37
|
+
* connector that carries a connections capability. */
|
|
38
|
+
export function byoConnections(connectors) {
|
|
39
|
+
const brokers = connectors
|
|
40
|
+
.filter(hasConnections)
|
|
41
|
+
.map((connector) => ({ name: connector.name, connections: connector.connections }));
|
|
42
|
+
if (brokers.length === 0) {
|
|
43
|
+
throw new VendoError("validation", "byoConnections requires at least one connector with a connections capability");
|
|
44
|
+
}
|
|
45
|
+
function broker(name) {
|
|
46
|
+
if (name === undefined)
|
|
47
|
+
return brokers[0];
|
|
48
|
+
const found = brokers.find((candidate) => candidate.name === name);
|
|
49
|
+
if (!found)
|
|
50
|
+
throw new VendoError("not-found", `no connector named ${name} supports connections`);
|
|
51
|
+
return found;
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
posture: "byo",
|
|
55
|
+
async list(principal) {
|
|
56
|
+
const lists = await Promise.all(brokers.map((candidate) => candidate.connections.list(principal.subject)));
|
|
57
|
+
return lists.flat();
|
|
58
|
+
},
|
|
59
|
+
async initiate(principal, options) {
|
|
60
|
+
guardInitiatePrincipal(principal);
|
|
61
|
+
guardCallbackUrl(options.callbackUrl);
|
|
62
|
+
const target = broker(options.connector);
|
|
63
|
+
const initiated = await target.connections.initiate(principal.subject, options.toolkit, {
|
|
64
|
+
...(options.callbackUrl === undefined ? {} : { callbackUrl: options.callbackUrl }),
|
|
65
|
+
});
|
|
66
|
+
return { ...initiated, connector: target.name };
|
|
67
|
+
},
|
|
68
|
+
async status(principal, connector, connectionId) {
|
|
69
|
+
return broker(connector).connections.status(principal.subject, connectionId);
|
|
70
|
+
},
|
|
71
|
+
async disconnect(principal, connector, connectionId) {
|
|
72
|
+
await broker(connector).connections.disconnect(principal.subject, connectionId);
|
|
73
|
+
},
|
|
74
|
+
async catalog() {
|
|
75
|
+
const catalogs = await Promise.all(brokers.map(async (candidate) => {
|
|
76
|
+
const entries = await candidate.connections.listConnectable?.() ?? [];
|
|
77
|
+
return entries.map((entry) => ({ ...entry, connector: candidate.name }));
|
|
78
|
+
}));
|
|
79
|
+
return catalogs.flat();
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
84
|
+
/** The shared console error table (cloud-console.ts): 401/402 → cloud-required
|
|
85
|
+
* (fix your Cloud standing), wire-legal envelope codes forward as VendoErrors,
|
|
86
|
+
* and anything else (unknown codes, 5xx, non-JSON bodies) rides a plain Error
|
|
87
|
+
* with the server's code attached — never a "validation" error blaming the
|
|
88
|
+
* caller for the console misbehaving (hosted-store's posture). */
|
|
89
|
+
const raiseConnectionsError = (response) => raiseCloudError(response, "connections", (code, message) => {
|
|
90
|
+
throw Object.assign(new Error(message), { code: code ?? "unavailable" });
|
|
91
|
+
});
|
|
92
|
+
/** The Cloud adapter — the OSS side of the zero-key cloud seam: same surface,
|
|
93
|
+
* brokered by the Vendo Cloud console (which holds Vendo's Composio
|
|
94
|
+
* credentials). The console implementation is out of scope here; this defines
|
|
95
|
+
* the wire it must serve. */
|
|
96
|
+
export function cloudConnections(options) {
|
|
97
|
+
const base = (options.baseUrl ?? "https://console.vendo.run").replace(/\/$/, "");
|
|
98
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
99
|
+
// The key-authed console sender (cloud-console.ts): Bearer auth + deployment
|
|
100
|
+
// identity (the console meters usage from real traffic) + per-request abort
|
|
101
|
+
// timeout, raising through the shared error table on any non-2xx.
|
|
102
|
+
const send = consoleSender({
|
|
103
|
+
base,
|
|
104
|
+
mountPath: "",
|
|
105
|
+
apiKey: options.apiKey,
|
|
106
|
+
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
107
|
+
fetchImpl,
|
|
108
|
+
raise: raiseConnectionsError,
|
|
109
|
+
});
|
|
110
|
+
async function cloudFetch(path, init) {
|
|
111
|
+
const response = await send(path, {
|
|
112
|
+
...init,
|
|
113
|
+
headers: {
|
|
114
|
+
...(init?.body === undefined ? {} : { "content-type": "application/json" }),
|
|
115
|
+
...init?.headers,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
try {
|
|
119
|
+
return await response.json();
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// A 2xx that isn't JSON means a misdeployed Cloud base (an SPA host or
|
|
123
|
+
// reverse proxy that 200s unknown paths with text/html). Fail loudly —
|
|
124
|
+
// hosted-store's malformed-200 posture — instead of reading as an empty
|
|
125
|
+
// connections list (or a not-found account) forever.
|
|
126
|
+
throw new VendoError("validation", `Vendo Cloud connections returned a non-JSON ${response.status} response — check VENDO_CLOUD_URL`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const subjectQuery = (principal) => `subject=${encodeURIComponent(principal.subject)}`;
|
|
130
|
+
return {
|
|
131
|
+
posture: "cloud",
|
|
132
|
+
async list(principal) {
|
|
133
|
+
const payload = await cloudFetch(`/api/v1/connections?${subjectQuery(principal)}`);
|
|
134
|
+
if (!Array.isArray(payload.connections)) {
|
|
135
|
+
// A 2xx without the envelope is the SERVICE misbehaving — never
|
|
136
|
+
// indistinguishable from a genuinely empty connections panel.
|
|
137
|
+
throw new VendoError("validation", "Vendo Cloud connections returned an invalid list response (no connections array)");
|
|
138
|
+
}
|
|
139
|
+
return payload.connections;
|
|
140
|
+
},
|
|
141
|
+
async initiate(principal, options) {
|
|
142
|
+
guardInitiatePrincipal(principal);
|
|
143
|
+
guardCallbackUrl(options.callbackUrl);
|
|
144
|
+
const payload = await cloudFetch("/api/v1/connections/initiate", {
|
|
145
|
+
method: "POST",
|
|
146
|
+
body: JSON.stringify({
|
|
147
|
+
subject: principal.subject,
|
|
148
|
+
toolkit: options.toolkit,
|
|
149
|
+
...(options.connector === undefined ? {} : { connector: options.connector }),
|
|
150
|
+
...(options.callbackUrl === undefined ? {} : { callbackUrl: options.callbackUrl }),
|
|
151
|
+
}),
|
|
152
|
+
});
|
|
153
|
+
if (typeof payload.id !== "string" || typeof payload.redirectUrl !== "string") {
|
|
154
|
+
throw new VendoError("validation", "Vendo Cloud connect initiation returned no redirect URL");
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
id: payload.id,
|
|
158
|
+
connector: typeof payload.connector === "string" ? payload.connector : "composio",
|
|
159
|
+
redirectUrl: payload.redirectUrl,
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
async status(principal, connector, connectionId) {
|
|
163
|
+
const payload = await cloudFetch(`/api/v1/connections/${encodeURIComponent(connectionId)}?${subjectQuery(principal)}&connector=${encodeURIComponent(connector)}`);
|
|
164
|
+
return payload.connection ?? null;
|
|
165
|
+
},
|
|
166
|
+
async disconnect(principal, connector, connectionId) {
|
|
167
|
+
await cloudFetch(`/api/v1/connections/${encodeURIComponent(connectionId)}?${subjectQuery(principal)}&connector=${encodeURIComponent(connector)}`, { method: "DELETE" });
|
|
168
|
+
},
|
|
169
|
+
async catalog() {
|
|
170
|
+
const payload = await cloudFetch("/api/v1/connections/catalog");
|
|
171
|
+
const available = Array.isArray(payload.available) ? payload.available : [];
|
|
172
|
+
return options.apps === undefined
|
|
173
|
+
? available
|
|
174
|
+
: available.filter((entry) => options.apps.includes(entry.toolkit));
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
/** The no-broker fallback adapter: listing is honestly empty (the panel
|
|
179
|
+
* renders an empty state), any mutation explains what to configure. */
|
|
180
|
+
export function unconfiguredConnections() {
|
|
181
|
+
const refuse = () => {
|
|
182
|
+
throw new VendoError("not-implemented", "connected accounts are not configured: pass a Composio connector (composioConnector) to createVendo({ connectors }) or set VENDO_API_KEY for the Vendo Cloud broker");
|
|
183
|
+
};
|
|
184
|
+
return {
|
|
185
|
+
posture: false,
|
|
186
|
+
list: async () => [],
|
|
187
|
+
initiate: async () => refuse(),
|
|
188
|
+
status: async () => refuse(),
|
|
189
|
+
disconnect: async () => refuse(),
|
|
190
|
+
catalog: async () => [],
|
|
191
|
+
};
|
|
192
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Deployment-identity headers (cloud definition, interaction model): every
|
|
2
|
+
* key-authenticated Vendo Cloud request carries `x-vendo-deployment-host` and
|
|
3
|
+
* `x-vendo-deployment-name`; the console's shared auth middleware upserts the
|
|
4
|
+
* deployment inventory and meters usage from these on real service calls —
|
|
5
|
+
* there is no heartbeat. Shared by the CLI cloud client and the runtime Cloud
|
|
6
|
+
* adapters (connections, sandbox), so this module carries NO static Node
|
|
7
|
+
* import: builtins load through the runtime accessor (server.ts precedent)
|
|
8
|
+
* and every lookup fails soft to "unknown" on edge/Worker targets — identity
|
|
9
|
+
* headers must never take a request down. The console truncates and fails
|
|
10
|
+
* open on its side (parseDeploymentHeaders), so sending is always safe. */
|
|
11
|
+
/** The two identity headers for a key-authenticated Cloud request. */
|
|
12
|
+
export declare function deploymentIdentityHeaders(): Promise<Record<string, string>>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** Deployment-identity headers (cloud definition, interaction model): every
|
|
2
|
+
* key-authenticated Vendo Cloud request carries `x-vendo-deployment-host` and
|
|
3
|
+
* `x-vendo-deployment-name`; the console's shared auth middleware upserts the
|
|
4
|
+
* deployment inventory and meters usage from these on real service calls —
|
|
5
|
+
* there is no heartbeat. Shared by the CLI cloud client and the runtime Cloud
|
|
6
|
+
* adapters (connections, sandbox), so this module carries NO static Node
|
|
7
|
+
* import: builtins load through the runtime accessor (server.ts precedent)
|
|
8
|
+
* and every lookup fails soft to "unknown" on edge/Worker targets — identity
|
|
9
|
+
* headers must never take a request down. The console truncates and fails
|
|
10
|
+
* open on its side (parseDeploymentHeaders), so sending is always safe. */
|
|
11
|
+
function runtimeProcess() {
|
|
12
|
+
return globalThis.process;
|
|
13
|
+
}
|
|
14
|
+
function builtinModule(id) {
|
|
15
|
+
try {
|
|
16
|
+
return runtimeProcess()?.getBuiltinModule?.(id);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Non-Latin-1 or CR/LF header values make fetch throw "Cannot convert
|
|
23
|
+
* argument to a ByteString"; identity headers must never take a command
|
|
24
|
+
* down, so strip to printable ASCII and never send an empty value. */
|
|
25
|
+
function headerSafe(value) {
|
|
26
|
+
const printable = value.replace(/[^\x20-\x7e]+/g, "").trim();
|
|
27
|
+
return printable.length > 0 ? printable : "unknown";
|
|
28
|
+
}
|
|
29
|
+
/** Name is the nearest project identity: the cwd package name, cached per
|
|
30
|
+
* directory (a process can chdir between calls). */
|
|
31
|
+
const deploymentNames = new Map();
|
|
32
|
+
function resolveDeploymentName(cwd) {
|
|
33
|
+
let name = deploymentNames.get(cwd);
|
|
34
|
+
if (name === undefined) {
|
|
35
|
+
name = (async () => {
|
|
36
|
+
const path = builtinModule("node:path");
|
|
37
|
+
const fs = builtinModule("node:fs");
|
|
38
|
+
try {
|
|
39
|
+
const manifestPath = path === undefined ? `${cwd}/package.json` : path.join(cwd, "package.json");
|
|
40
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
41
|
+
if (typeof manifest.name === "string" && manifest.name.length > 0)
|
|
42
|
+
return manifest.name;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// no manifest (or no filesystem) — fall through to the directory name
|
|
46
|
+
}
|
|
47
|
+
if (path !== undefined)
|
|
48
|
+
return path.basename(cwd);
|
|
49
|
+
return cwd.split(/[/\\]/).filter(Boolean).pop() ?? "";
|
|
50
|
+
})();
|
|
51
|
+
deploymentNames.set(cwd, name);
|
|
52
|
+
}
|
|
53
|
+
return name;
|
|
54
|
+
}
|
|
55
|
+
/** The two identity headers for a key-authenticated Cloud request. */
|
|
56
|
+
export async function deploymentIdentityHeaders() {
|
|
57
|
+
const os = builtinModule("node:os");
|
|
58
|
+
let cwd;
|
|
59
|
+
try {
|
|
60
|
+
cwd = runtimeProcess()?.cwd?.();
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
cwd = undefined;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
"x-vendo-deployment-host": headerSafe(os === undefined ? "" : os.hostname()),
|
|
67
|
+
"x-vendo-deployment-name": headerSafe(cwd === undefined ? "" : await resolveDeploymentName(cwd)),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { LanguageModel } from "ai";
|
|
2
|
+
import { type DevCredential } from "./resolve.js";
|
|
3
|
+
/**
|
|
4
|
+
* `devModel()` — the env-resolving model createVendo composes when the host
|
|
5
|
+
* passes none (install-dx v1: `model` is optional; real keys only). It IS an
|
|
6
|
+
* ai-SDK LanguageModel (BYO seam unchanged, 03-agent §1), resolving the
|
|
7
|
+
* credential lazily on first use:
|
|
8
|
+
*
|
|
9
|
+
* - env-key rungs delegate to the host-installed @ai-sdk provider (^3, spec
|
|
10
|
+
* v3) with full native tool calling — works in production too.
|
|
11
|
+
* - VENDO_API_KEY delegates to the Vendo Cloud model gateway: the
|
|
12
|
+
* host-installed @ai-sdk/anthropic pointed at `<console>/api/v1`, whose
|
|
13
|
+
* Anthropic-compatible /messages endpoint serves the metered dev-mode
|
|
14
|
+
* allowance under curated model aliases (vendo-default by default).
|
|
15
|
+
* - nothing available → every call fails with the exact instructions.
|
|
16
|
+
*/
|
|
17
|
+
export interface DevModelOptions {
|
|
18
|
+
/** Host app root; providers resolve from here. Default cwd. */
|
|
19
|
+
root?: string;
|
|
20
|
+
env?: Record<string, string | undefined>;
|
|
21
|
+
/** Test seam for host-module resolution (providers). */
|
|
22
|
+
importModule?: (root: string, specifier: string) => Promise<Record<string, unknown>>;
|
|
23
|
+
}
|
|
24
|
+
interface LanguageModelV3Like {
|
|
25
|
+
specificationVersion: "v3";
|
|
26
|
+
provider: string;
|
|
27
|
+
modelId: string;
|
|
28
|
+
supportedUrls: Record<string, RegExp[]>;
|
|
29
|
+
doGenerate(options: unknown): PromiseLike<unknown>;
|
|
30
|
+
doStream(options: unknown): PromiseLike<unknown>;
|
|
31
|
+
}
|
|
32
|
+
type Resolution = {
|
|
33
|
+
mode: "delegate";
|
|
34
|
+
credential: DevCredential;
|
|
35
|
+
model: LanguageModelV3Like;
|
|
36
|
+
} | {
|
|
37
|
+
mode: "unavailable";
|
|
38
|
+
credential: DevCredential;
|
|
39
|
+
message: string;
|
|
40
|
+
};
|
|
41
|
+
export declare const NO_CREDENTIAL_MESSAGE: string;
|
|
42
|
+
export declare class DevModelController {
|
|
43
|
+
private readonly root;
|
|
44
|
+
private readonly env;
|
|
45
|
+
private readonly importModule;
|
|
46
|
+
private resolution;
|
|
47
|
+
private announced;
|
|
48
|
+
constructor(options?: DevModelOptions);
|
|
49
|
+
/** Resolve the credential once per process; state it on the server log once.
|
|
50
|
+
* An unavailable resolution logs its full instructions HERE — the wire
|
|
51
|
+
* deliberately shows clients only a generic error, so the operator's
|
|
52
|
+
* terminal is where the honest message must land. */
|
|
53
|
+
resolve(): Promise<Resolution>;
|
|
54
|
+
private announce;
|
|
55
|
+
/** The shared delegate rung: load the provider module (an install failure
|
|
56
|
+
* resolves unavailable with the exact install command), pick the model id
|
|
57
|
+
* (env override or the spec default), and hand the factory-built model back. */
|
|
58
|
+
private delegate;
|
|
59
|
+
private resolveOnce;
|
|
60
|
+
doGenerate(callOptions: unknown): Promise<unknown>;
|
|
61
|
+
doStream(callOptions: unknown): Promise<unknown>;
|
|
62
|
+
}
|
|
63
|
+
/** The env-resolving model (see module doc). */
|
|
64
|
+
export declare function devModel(options?: DevModelOptions): LanguageModel;
|
|
65
|
+
export {};
|