@vendoai/agent 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.
Files changed (51) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +26 -0
  3. package/dist/agent.d.ts +62 -0
  4. package/dist/agent.d.ts.map +1 -0
  5. package/dist/agent.js +443 -0
  6. package/dist/agent.js.map +1 -0
  7. package/dist/capability-miss.d.ts +24 -0
  8. package/dist/capability-miss.d.ts.map +1 -0
  9. package/dist/capability-miss.js +133 -0
  10. package/dist/capability-miss.js.map +1 -0
  11. package/dist/ids.d.ts +6 -0
  12. package/dist/ids.d.ts.map +1 -0
  13. package/dist/ids.js +9 -0
  14. package/dist/ids.js.map +1 -0
  15. package/dist/index.d.ts +8 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +4 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/pack.d.ts +37 -0
  20. package/dist/pack.d.ts.map +1 -0
  21. package/dist/pack.js +225 -0
  22. package/dist/pack.js.map +1 -0
  23. package/dist/prompt.d.ts +8 -0
  24. package/dist/prompt.d.ts.map +1 -0
  25. package/dist/prompt.js +43 -0
  26. package/dist/prompt.js.map +1 -0
  27. package/dist/runner.d.ts +20 -0
  28. package/dist/runner.d.ts.map +1 -0
  29. package/dist/runner.js +114 -0
  30. package/dist/runner.js.map +1 -0
  31. package/dist/test-helpers.d.ts +55 -0
  32. package/dist/test-helpers.d.ts.map +1 -0
  33. package/dist/test-helpers.js +230 -0
  34. package/dist/test-helpers.js.map +1 -0
  35. package/dist/threads.d.ts +48 -0
  36. package/dist/threads.d.ts.map +1 -0
  37. package/dist/threads.js +251 -0
  38. package/dist/threads.js.map +1 -0
  39. package/dist/tool-pack.d.ts +41 -0
  40. package/dist/tool-pack.d.ts.map +1 -0
  41. package/dist/tool-pack.js +17 -0
  42. package/dist/tool-pack.js.map +1 -0
  43. package/dist/tool-search.d.ts +72 -0
  44. package/dist/tool-search.d.ts.map +1 -0
  45. package/dist/tool-search.js +135 -0
  46. package/dist/tool-search.js.map +1 -0
  47. package/dist/tools.d.ts +22 -0
  48. package/dist/tools.d.ts.map +1 -0
  49. package/dist/tools.js +151 -0
  50. package/dist/tools.js.map +1 -0
  51. package/package.json +63 -0
@@ -0,0 +1,72 @@
1
+ import { type RiskLabel, type RunContext, type ToolDescriptor } from "@vendoai/core";
2
+ import { type ToolSet } from "ai";
3
+ /** The meta-tool the agent uses to discover and load host tools mid-run. */
4
+ export declare const VENDO_TOOLS_SEARCH_TOOL_NAME = "vendo_tools_search";
5
+ /** Default bound on the uncurated initial loadout. A large host (dub ≈ 617
6
+ * tools, papermark ≈ 388) would otherwise flood the model's context; the rest
7
+ * stay reachable through {@link VENDO_TOOLS_SEARCH_TOOL_NAME}. */
8
+ export declare const DEFAULT_MAX_INITIAL_TOOLS = 128;
9
+ /** A hit from the injected search seam — the structural twin of actions'
10
+ * `ToolSearchMatch` (the agent block depends on core only, so it cannot import
11
+ * the actions type). */
12
+ export interface ToolSearchMatch {
13
+ name: string;
14
+ description: string;
15
+ risk: RiskLabel;
16
+ score: number;
17
+ }
18
+ /** Ranks the merged, enabled, guard-bound tool surface against a free-text
19
+ * intent. The umbrella wires this to `ActionsRegistry.search`. */
20
+ export type ToolSearchFn = (query: string, options?: {
21
+ limit?: number;
22
+ }) => Promise<ToolSearchMatch[]>;
23
+ export interface ToolSearchConfig {
24
+ /** The registry query seam (umbrella wires it to the guard-bound registry). */
25
+ search: ToolSearchFn;
26
+ /** Uncurated loadout cap. Defaults to {@link DEFAULT_MAX_INITIAL_TOOLS}. */
27
+ maxInitialTools?: number;
28
+ /** Explicit curated initial loadout by tool name. When set, exactly these
29
+ * (that exist and are enabled) start active; the cap is not applied. */
30
+ loadout?: string[];
31
+ /** Per-turn initial-loadout seed (connection-scoped tool loading, spec
32
+ * 2026-07-20): typically the connected toolkits' tools — the umbrella
33
+ * wires this to registry.loadoutSeed(connectedToolkits). Runs BEFORE the
34
+ * toolset is built so freshly expanded tools are included. A failure
35
+ * degrades to the risk/name fallback, never the turn. */
36
+ seed?: (ctx: RunContext) => Promise<string[] | undefined>;
37
+ }
38
+ /**
39
+ * The INITIAL enabled set (loadout policy, ENG-252 spec §4):
40
+ * - Explicit `loadout` present → exactly those names that exist, deduped
41
+ * (curation, e.g. derived from overrides).
42
+ * - Otherwise, if the enabled host surface fits the cap → the whole surface.
43
+ * - Otherwise (uncurated + large) → a deterministic bounded default: safest
44
+ * risk first (read < write < destructive), then name, capped. The remainder
45
+ * stays discoverable via search.
46
+ * Vendo's own `vendo_*` tools are always active and excluded from the cap.
47
+ */
48
+ export declare function computeInitialLoadout(descriptors: readonly ToolDescriptor[], config: ToolSearchConfig, seedNames?: readonly string[]): Set<string>;
49
+ export interface ToolSearchSession {
50
+ /** Names the model may call this step: initial loadout ∪ everything loaded so
51
+ * far ∪ the always-active `vendo_*` tools (which include this meta-tool). */
52
+ activeToolNames(): string[];
53
+ /** Register `vendo_tools_search` into the run's toolset. */
54
+ attach(tools: ToolSet): void;
55
+ }
56
+ export interface ToolSearchSessionOptions {
57
+ config: ToolSearchConfig;
58
+ /** The full built toolset's descriptors (names available to load). */
59
+ descriptors: readonly ToolDescriptor[];
60
+ /** Per-run loaded set — persists across turns within a thread. Mutated here. */
61
+ loaded: Set<string>;
62
+ /** Per-turn seed for the initial loadout (see ToolSearchConfig.seed). */
63
+ seedNames?: readonly string[];
64
+ /** Full descriptors for names search returned that are NOT yet in the built
65
+ * toolset — they were lazily expanded during the search itself. */
66
+ resolve?: (names: string[]) => Promise<ToolDescriptor[]>;
67
+ /** Add a freshly resolved descriptor into the LIVE toolset. prepareStep
68
+ * re-reads activeToolNames() each step, so it's callable next step. */
69
+ materialize?: (descriptor: ToolDescriptor) => void;
70
+ }
71
+ export declare function createToolSearchSession(options: ToolSearchSessionOptions): ToolSearchSession;
72
+ //# sourceMappingURL=tool-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-search.d.ts","sourceRoot":"","sources":["../src/tool-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,cAAc,EAEpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAA2B,KAAK,OAAO,EAAE,MAAM,IAAI,CAAC;AAE3D,4EAA4E;AAC5E,eAAO,MAAM,4BAA4B,uBAAuB,CAAC;AAEjE;;kEAEkE;AAClE,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAI7C;;wBAEwB;AACxB,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;kEACkE;AAClE,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;AAEvG,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,MAAM,EAAE,YAAY,CAAC;IACrB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;6EACyE;IACzE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;;8DAI0D;IAC1D,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;CAC3D;AAoBD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,SAAS,cAAc,EAAE,EACtC,MAAM,EAAE,gBAAgB,EACxB,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,GAC5B,GAAG,CAAC,MAAM,CAAC,CAwBb;AAED,MAAM,WAAW,iBAAiB;IAChC;kFAC8E;IAC9E,eAAe,IAAI,MAAM,EAAE,CAAC;IAC5B,4DAA4D;IAC5D,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,gBAAgB,CAAC;IACzB,sEAAsE;IACtE,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IACvC,gFAAgF;IAChF,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,yEAAyE;IACzE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B;uEACmE;IACnE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACzD;2EACuE;IACvE,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,KAAK,IAAI,CAAC;CACpD;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB,CAwE5F"}
@@ -0,0 +1,135 @@
1
+ import { VendoError, } from "@vendoai/core";
2
+ import { dynamicTool, jsonSchema } from "ai";
3
+ /** The meta-tool the agent uses to discover and load host tools mid-run. */
4
+ export const VENDO_TOOLS_SEARCH_TOOL_NAME = "vendo_tools_search";
5
+ /** Default bound on the uncurated initial loadout. A large host (dub ≈ 617
6
+ * tools, papermark ≈ 388) would otherwise flood the model's context; the rest
7
+ * stay reachable through {@link VENDO_TOOLS_SEARCH_TOOL_NAME}. */
8
+ export const DEFAULT_MAX_INITIAL_TOOLS = 128;
9
+ const RISK_ORDER = { read: 0, write: 1, destructive: 2 };
10
+ const SEARCH_INPUT_SCHEMA = {
11
+ type: "object",
12
+ properties: {
13
+ query: { type: "string", minLength: 1, maxLength: 200 },
14
+ limit: { type: "integer", minimum: 1, maximum: 25 },
15
+ },
16
+ required: ["query"],
17
+ additionalProperties: false,
18
+ };
19
+ /** Vendo's own always-available tools (apps, connect, the meta-tools) are never
20
+ * loadout-gated: they are not host API tools that explode in number, and gating
21
+ * them out would break the product surface. Everything `vendo_`-prefixed stays
22
+ * active; host tools are what the loadout bounds. */
23
+ function isAlwaysActive(name) {
24
+ return name.startsWith("vendo_");
25
+ }
26
+ /**
27
+ * The INITIAL enabled set (loadout policy, ENG-252 spec §4):
28
+ * - Explicit `loadout` present → exactly those names that exist, deduped
29
+ * (curation, e.g. derived from overrides).
30
+ * - Otherwise, if the enabled host surface fits the cap → the whole surface.
31
+ * - Otherwise (uncurated + large) → a deterministic bounded default: safest
32
+ * risk first (read < write < destructive), then name, capped. The remainder
33
+ * stays discoverable via search.
34
+ * Vendo's own `vendo_*` tools are always active and excluded from the cap.
35
+ */
36
+ export function computeInitialLoadout(descriptors, config, seedNames) {
37
+ const available = new Set(descriptors.map((descriptor) => descriptor.name));
38
+ const alwaysActive = descriptors.filter((descriptor) => isAlwaysActive(descriptor.name)).map((d) => d.name);
39
+ const hostTools = descriptors.filter((descriptor) => !isAlwaysActive(descriptor.name));
40
+ if (config.loadout !== undefined) {
41
+ return new Set([...alwaysActive, ...config.loadout.filter((name) => available.has(name))]);
42
+ }
43
+ const cap = Math.max(Math.trunc(config.maxInitialTools ?? DEFAULT_MAX_INITIAL_TOOLS), 1);
44
+ // Connection-scoped seed: exactly the relevant tools (host tools + the
45
+ // principal's connected toolkits), capped — never an alphabetical slice.
46
+ if (seedNames !== undefined) {
47
+ const seeded = seedNames.filter((name) => available.has(name) && !isAlwaysActive(name)).slice(0, cap);
48
+ return new Set([...alwaysActive, ...seeded]);
49
+ }
50
+ if (hostTools.length <= cap)
51
+ return new Set([...alwaysActive, ...hostTools.map((d) => d.name)]);
52
+ const bounded = [...hostTools]
53
+ .sort((a, b) => (RISK_ORDER[a.risk] - RISK_ORDER[b.risk]) || (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))
54
+ .slice(0, cap)
55
+ .map((descriptor) => descriptor.name);
56
+ return new Set([...alwaysActive, ...bounded]);
57
+ }
58
+ export function createToolSearchSession(options) {
59
+ const available = new Set(options.descriptors.map((descriptor) => descriptor.name));
60
+ const initial = computeInitialLoadout(options.descriptors, options.config, options.seedNames);
61
+ // Captured at attach: the full run toolset. Every Vendo-owned `vendo_*` tool
62
+ // in it stays active regardless of loadout — including the OTHER meta-tools
63
+ // (notably `vendo_report_capability_miss`) that are attached after the host
64
+ // descriptors and so are NOT in `options.descriptors`. Gating them out would
65
+ // silently disable miss capture whenever tool search is on.
66
+ let attached;
67
+ return {
68
+ activeToolNames() {
69
+ const active = new Set(initial);
70
+ active.add(VENDO_TOOLS_SEARCH_TOOL_NAME);
71
+ for (const name of Object.keys(attached ?? {}))
72
+ if (isAlwaysActive(name))
73
+ active.add(name);
74
+ for (const name of options.loaded)
75
+ if (available.has(name))
76
+ active.add(name);
77
+ return [...active];
78
+ },
79
+ attach(tools) {
80
+ attached = tools;
81
+ if (tools[VENDO_TOOLS_SEARCH_TOOL_NAME] !== undefined) {
82
+ throw new VendoError("conflict", `Reserved internal tool name: ${VENDO_TOOLS_SEARCH_TOOL_NAME}`);
83
+ }
84
+ tools[VENDO_TOOLS_SEARCH_TOOL_NAME] = dynamicTool({
85
+ description: "Search ALL of this product's tools and connected-service tools by intent, and LOAD the matches so you can call them this run. "
86
+ + "Results may include tools for services the user has NOT connected yet — calling one is safe and correct: the user is prompted to connect in-line. "
87
+ + "Use this whenever no currently-available tool fits the ask.",
88
+ inputSchema: jsonSchema(SEARCH_INPUT_SCHEMA),
89
+ execute: async (input) => {
90
+ const parsed = input;
91
+ const query = typeof parsed?.query === "string" ? parsed.query : "";
92
+ if (query.trim().length === 0) {
93
+ return { status: "error", error: { code: "validation", message: "query must be a non-empty string" } };
94
+ }
95
+ const limit = typeof parsed?.limit === "number" ? parsed.limit : undefined;
96
+ let matches;
97
+ try {
98
+ matches = await options.config.search(query, limit === undefined ? undefined : { limit });
99
+ }
100
+ catch {
101
+ return { status: "error", error: { code: "execution", message: "Tool search failed." } };
102
+ }
103
+ // Names outside the built toolset were lazily expanded during this
104
+ // very search — resolve their full descriptors and materialize them
105
+ // into the LIVE toolset so they are callable next step.
106
+ const missing = matches.filter((match) => !available.has(match.name)).map((match) => match.name);
107
+ if (missing.length > 0 && options.resolve !== undefined && options.materialize !== undefined) {
108
+ try {
109
+ for (const descriptor of await options.resolve(missing)) {
110
+ options.materialize(descriptor);
111
+ available.add(descriptor.name);
112
+ }
113
+ }
114
+ catch {
115
+ // Unresolved names simply stay unloadable below.
116
+ }
117
+ }
118
+ // Only load names that actually exist in this run's guard-bound toolset
119
+ // — a stale or drifting search seam can never conjure an unbound tool.
120
+ const loadable = matches.filter((match) => available.has(match.name));
121
+ for (const match of loadable)
122
+ options.loaded.add(match.name);
123
+ return {
124
+ status: "ok",
125
+ output: {
126
+ loaded: loadable.map((match) => match.name),
127
+ tools: loadable.map((match) => ({ name: match.name, description: match.description, risk: match.risk })),
128
+ },
129
+ };
130
+ },
131
+ });
132
+ },
133
+ };
134
+ }
135
+ //# sourceMappingURL=tool-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-search.js","sourceRoot":"","sources":["../src/tool-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type ApprovalId, type Guard, type RiskLabel, type RunContext, type ToolCall, type ToolDescriptor, type ToolOutcome, type ToolRegistry, type VendoApprovalPart } from "@vendoai/core";
2
+ import { type ToolSet, type UIMessage, type UIMessageStreamWriter } from "ai";
3
+ /** 03-agent §2 */
4
+ export interface ToolBridgeOptions {
5
+ registry: ToolRegistry;
6
+ ctx: RunContext;
7
+ guard?: Guard;
8
+ writer?: UIMessageStreamWriter<UIMessage>;
9
+ toolOutputCap?: number;
10
+ gate?: (call: ToolCall) => ToolOutcome | undefined;
11
+ onCall?: (call: ToolCall) => (outcome: ToolOutcome) => void;
12
+ }
13
+ /** The flat §16 approval part shared by every consent surface (native
14
+ * needsApproval, pending-approval outcomes). */
15
+ export declare function approvalPart(toolCallId: string, risk: RiskLabel, approvalId: ApprovalId, invalidatedGrant?: VendoApprovalPart["invalidatedGrant"]): VendoApprovalPart;
16
+ /** 03-agent §2 */
17
+ export declare function buildAgentTools(options: ToolBridgeOptions): Promise<ToolSet>;
18
+ /** Build ONE guard-bound agent tool and insert it into `tools`. Exported so a
19
+ * tool lazily expanded mid-turn (vendo_tools_search, spec 2026-07-20)
20
+ * materializes with the exact wrapper the boot-time toolset uses. */
21
+ export declare function addAgentTool(tools: ToolSet, descriptor: ToolDescriptor, options: ToolBridgeOptions): void;
22
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,UAAU,EACf,KAAK,KAAK,EACV,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EAIvB,MAAM,eAAe,CAAC;AACvB,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC3B,MAAM,IAAI,CAAC;AAIZ,kBAAkB;AAClB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,YAAY,CAAC;IACvB,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,MAAM,CAAC,EAAE,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,WAAW,GAAG,SAAS,CAAC;IACnD,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;CAC7D;AAcD;iDACiD;AACjD,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,UAAU,EACtB,gBAAgB,CAAC,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,GACvD,iBAAiB,CAQnB;AA+BD,kBAAkB;AAClB,wBAAsB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAKlF;AAED;;qEAEqE;AACrE,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CA6FzG"}
package/dist/tools.js ADDED
@@ -0,0 +1,151 @@
1
+ import { VENDO_APPS_CREATE_TOOL, VENDO_APPS_TOOL_PREFIX, VENDO_VIEW_STREAM, toVendoWirePart, vendoViewStreamId, vendoViewPartSchema, } from "@vendoai/core";
2
+ import { dynamicTool, jsonSchema, } from "ai";
3
+ function writePart(writer, part, id) {
4
+ if (!writer)
5
+ return;
6
+ // The ai-SDK UI message stream requires custom data chunks to carry their
7
+ // payload under `data` ({ type: "data-*", data }); the stock client's chunk
8
+ // schema hard-rejects the flat form. Core owns that envelope (AGENT-10).
9
+ writer.write(toVendoWirePart(part, id));
10
+ }
11
+ /** The flat §16 approval part shared by every consent surface (native
12
+ * needsApproval, pending-approval outcomes). */
13
+ export function approvalPart(toolCallId, risk, approvalId, invalidatedGrant) {
14
+ return {
15
+ type: "data-vendo-approval",
16
+ toolCallId,
17
+ risk,
18
+ approvalId,
19
+ ...(invalidatedGrant === undefined ? {} : { invalidatedGrant }),
20
+ };
21
+ }
22
+ function executionError() {
23
+ return {
24
+ status: "error",
25
+ error: {
26
+ code: "execution",
27
+ message: "Tool execution failed.",
28
+ },
29
+ };
30
+ }
31
+ function capOutcome(outcome, cap) {
32
+ if (outcome.status !== "ok" || cap === undefined)
33
+ return outcome;
34
+ let serialized;
35
+ try {
36
+ serialized = JSON.stringify(outcome.output);
37
+ }
38
+ catch {
39
+ return executionError();
40
+ }
41
+ if (serialized === undefined || serialized.length <= cap)
42
+ return outcome;
43
+ return {
44
+ status: "ok",
45
+ output: {
46
+ truncated: true,
47
+ chars: serialized.length,
48
+ preview: serialized.slice(0, cap),
49
+ },
50
+ };
51
+ }
52
+ /** 03-agent §2 */
53
+ export async function buildAgentTools(options) {
54
+ const descriptors = await options.registry.descriptors();
55
+ const tools = {};
56
+ for (const descriptor of descriptors)
57
+ addAgentTool(tools, descriptor, options);
58
+ return tools;
59
+ }
60
+ /** Build ONE guard-bound agent tool and insert it into `tools`. Exported so a
61
+ * tool lazily expanded mid-turn (vendo_tools_search, spec 2026-07-20)
62
+ * materializes with the exact wrapper the boot-time toolset uses. */
63
+ export function addAgentTool(tools, descriptor, options) {
64
+ {
65
+ const execute = async (input, { toolCallId }) => {
66
+ const call = { id: toolCallId, tool: descriptor.name, args: input };
67
+ if (descriptor.name === VENDO_APPS_CREATE_TOOL && options.writer !== undefined) {
68
+ Object.defineProperty(call, VENDO_VIEW_STREAM, {
69
+ value: (update) => {
70
+ const view = vendoViewPartSchema.safeParse(update.part);
71
+ if (view.success)
72
+ writePart(options.writer, view.data, update.id);
73
+ },
74
+ });
75
+ }
76
+ const finishCall = options.onCall?.(call);
77
+ let outcome = options.gate?.(call);
78
+ if (outcome === undefined) {
79
+ try {
80
+ outcome = await options.registry.execute(call, options.ctx);
81
+ }
82
+ catch {
83
+ outcome = executionError();
84
+ }
85
+ }
86
+ // A view part is emitted ONLY from the app runtime's own view-producing
87
+ // tools returning a tree OpenSurface (06 §1) — never by duck-typing an
88
+ // arbitrary host tool's output, which could otherwise smuggle an unrelated
89
+ // result onto the app-view channel and mis-route its actions (01 §16).
90
+ const producesView = descriptor.name.startsWith(VENDO_APPS_TOOL_PREFIX);
91
+ if (outcome.status === "ok" && producesView) {
92
+ const surface = typeof outcome.output === "object" && outcome.output !== null
93
+ ? outcome.output
94
+ : undefined;
95
+ const args = typeof input === "object" && input !== null
96
+ ? input
97
+ : undefined;
98
+ const candidate = surface?.kind === "tree" && surface.payload !== undefined
99
+ ? {
100
+ type: "data-vendo-view",
101
+ // OpenSurface carries no app id (06 §1); the open call's own appId
102
+ // argument identifies the app this payload belongs to.
103
+ appId: surface.appId ?? args?.appId,
104
+ payload: surface.payload,
105
+ }
106
+ : null;
107
+ const view = vendoViewPartSchema.safeParse(candidate);
108
+ if (view.success)
109
+ writePart(options.writer, view.data, vendoViewStreamId(view.data.appId));
110
+ }
111
+ else if (outcome.status === "pending-approval") {
112
+ writePart(options.writer, approvalPart(toolCallId, descriptor.risk, outcome.approvalId));
113
+ }
114
+ else if (outcome.status === "connect-required") {
115
+ // The inline connect card (04-actions §3): emitted beside the native
116
+ // tool part exactly like the approval part, keyed by toolCallId.
117
+ writePart(options.writer, {
118
+ type: "data-vendo-connect",
119
+ toolCallId,
120
+ connector: outcome.connect.connector,
121
+ toolkit: outcome.connect.toolkit,
122
+ message: outcome.connect.message,
123
+ });
124
+ }
125
+ const modelOutcome = capOutcome(outcome, options.toolOutputCap);
126
+ finishCall?.(modelOutcome);
127
+ return modelOutcome;
128
+ };
129
+ const needsApproval = options.guard
130
+ ? async (input, { toolCallId }) => {
131
+ try {
132
+ const decision = await options.guard.check({ id: toolCallId, tool: descriptor.name, args: input }, descriptor, options.ctx);
133
+ if (decision.action !== "ask")
134
+ return false;
135
+ writePart(options.writer, approvalPart(toolCallId, descriptor.risk, decision.approval.id, decision.approval.invalidatedGrant));
136
+ return true;
137
+ }
138
+ catch {
139
+ return true;
140
+ }
141
+ }
142
+ : undefined;
143
+ tools[descriptor.name] = dynamicTool({
144
+ description: descriptor.description,
145
+ inputSchema: jsonSchema(descriptor.inputSchema),
146
+ execute,
147
+ ...(needsApproval ? { needsApproval } : {}),
148
+ });
149
+ }
150
+ }
151
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@vendoai/agent",
3
+ "version": "0.4.0",
4
+ "description": "The Vendo agent loop: streaming, tool-calling, context engineering — BYO ai-SDK LanguageModel, guard-bound tools, thread persistence via the store seam.",
5
+ "keywords": [
6
+ "ai",
7
+ "agent",
8
+ "vendo",
9
+ "llm",
10
+ "streaming"
11
+ ],
12
+ "license": "Apache-2.0",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/runvendo/vendo.git",
16
+ "directory": "packages/agent"
17
+ },
18
+ "homepage": "https://vendo.run",
19
+ "bugs": "https://github.com/runvendo/vendo/issues",
20
+ "engines": {
21
+ "node": ">=20"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "type": "module",
27
+ "sideEffects": false,
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ }
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "README.md"
39
+ ],
40
+ "dependencies": {
41
+ "zod": "^3.25.76",
42
+ "@vendoai/core": "0.4.0"
43
+ },
44
+ "peerDependencies": {
45
+ "ai": ">=6.0.0 <7"
46
+ },
47
+ "devDependencies": {
48
+ "@ai-sdk/anthropic": "3.0.12",
49
+ "@ai-sdk/openai": "3.0.9",
50
+ "@ai-sdk/openai-compatible": "2.0.9",
51
+ "@types/node": "^22.0.0",
52
+ "ai": "6.0.28",
53
+ "typescript": "^5.6.0",
54
+ "vitest": "^2.1.0"
55
+ },
56
+ "scripts": {
57
+ "build": "tsc -p tsconfig.json",
58
+ "conformance": "vitest run src/conformance.test.ts src/wire.test.ts src/stream-client.test.ts src/provider-wire.conformance.test.ts",
59
+ "test": "vitest run",
60
+ "typecheck": "tsc -p tsconfig.json --noEmit",
61
+ "test:coverage": "vitest run --coverage"
62
+ }
63
+ }