@buoy-gg/agent-core 7.0.33

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 (138) hide show
  1. package/LICENSE +58 -0
  2. package/README.md +42 -0
  3. package/lib/commonjs/blocks/receipts.js +702 -0
  4. package/lib/commonjs/blocks/receipts.js.map +1 -0
  5. package/lib/commonjs/blocks/types.js +119 -0
  6. package/lib/commonjs/blocks/types.js.map +1 -0
  7. package/lib/commonjs/blocks/uiTool.js +994 -0
  8. package/lib/commonjs/blocks/uiTool.js.map +1 -0
  9. package/lib/commonjs/catalog/catalog.g.js +4044 -0
  10. package/lib/commonjs/catalog/catalog.g.js.map +1 -0
  11. package/lib/commonjs/catalog/catalog.source.json +4956 -0
  12. package/lib/commonjs/catalog/snapshotReads.js +256 -0
  13. package/lib/commonjs/catalog/snapshotReads.js.map +1 -0
  14. package/lib/commonjs/catalog/toProviderTools.js +107 -0
  15. package/lib/commonjs/catalog/toProviderTools.js.map +1 -0
  16. package/lib/commonjs/catalog/validateParams.js +129 -0
  17. package/lib/commonjs/catalog/validateParams.js.map +1 -0
  18. package/lib/commonjs/context/buildContextPack.js +141 -0
  19. package/lib/commonjs/context/buildContextPack.js.map +1 -0
  20. package/lib/commonjs/effects/ledger.js +229 -0
  21. package/lib/commonjs/effects/ledger.js.map +1 -0
  22. package/lib/commonjs/engine/effectFor.js +95 -0
  23. package/lib/commonjs/engine/effectFor.js.map +1 -0
  24. package/lib/commonjs/engine/runAgentTurn.js +667 -0
  25. package/lib/commonjs/engine/runAgentTurn.js.map +1 -0
  26. package/lib/commonjs/engine/systemPrompt.js +86 -0
  27. package/lib/commonjs/engine/systemPrompt.js.map +1 -0
  28. package/lib/commonjs/index.js +288 -0
  29. package/lib/commonjs/index.js.map +1 -0
  30. package/lib/commonjs/package.json +1 -0
  31. package/lib/commonjs/policy/labels.js +303 -0
  32. package/lib/commonjs/policy/labels.js.map +1 -0
  33. package/lib/commonjs/policy/policy.js +143 -0
  34. package/lib/commonjs/policy/policy.js.map +1 -0
  35. package/lib/commonjs/policy/redact.js +135 -0
  36. package/lib/commonjs/policy/redact.js.map +1 -0
  37. package/lib/commonjs/providers/anthropic.js +272 -0
  38. package/lib/commonjs/providers/anthropic.js.map +1 -0
  39. package/lib/commonjs/providers/openai.js +193 -0
  40. package/lib/commonjs/providers/openai.js.map +1 -0
  41. package/lib/commonjs/providers/sse.js +104 -0
  42. package/lib/commonjs/providers/sse.js.map +1 -0
  43. package/lib/commonjs/providers/types.js +6 -0
  44. package/lib/commonjs/providers/types.js.map +1 -0
  45. package/lib/commonjs/session.js +173 -0
  46. package/lib/commonjs/session.js.map +1 -0
  47. package/lib/commonjs/types.js +2 -0
  48. package/lib/commonjs/types.js.map +1 -0
  49. package/lib/module/blocks/receipts.js +696 -0
  50. package/lib/module/blocks/receipts.js.map +1 -0
  51. package/lib/module/blocks/types.js +113 -0
  52. package/lib/module/blocks/types.js.map +1 -0
  53. package/lib/module/blocks/uiTool.js +987 -0
  54. package/lib/module/blocks/uiTool.js.map +1 -0
  55. package/lib/module/catalog/catalog.g.js +4040 -0
  56. package/lib/module/catalog/catalog.g.js.map +1 -0
  57. package/lib/module/catalog/catalog.source.json +4956 -0
  58. package/lib/module/catalog/snapshotReads.js +252 -0
  59. package/lib/module/catalog/snapshotReads.js.map +1 -0
  60. package/lib/module/catalog/toProviderTools.js +101 -0
  61. package/lib/module/catalog/toProviderTools.js.map +1 -0
  62. package/lib/module/catalog/validateParams.js +124 -0
  63. package/lib/module/catalog/validateParams.js.map +1 -0
  64. package/lib/module/context/buildContextPack.js +138 -0
  65. package/lib/module/context/buildContextPack.js.map +1 -0
  66. package/lib/module/effects/ledger.js +223 -0
  67. package/lib/module/effects/ledger.js.map +1 -0
  68. package/lib/module/engine/effectFor.js +91 -0
  69. package/lib/module/engine/effectFor.js.map +1 -0
  70. package/lib/module/engine/runAgentTurn.js +663 -0
  71. package/lib/module/engine/runAgentTurn.js.map +1 -0
  72. package/lib/module/engine/systemPrompt.js +82 -0
  73. package/lib/module/engine/systemPrompt.js.map +1 -0
  74. package/lib/module/index.js +30 -0
  75. package/lib/module/index.js.map +1 -0
  76. package/lib/module/policy/labels.js +296 -0
  77. package/lib/module/policy/labels.js.map +1 -0
  78. package/lib/module/policy/policy.js +137 -0
  79. package/lib/module/policy/policy.js.map +1 -0
  80. package/lib/module/policy/redact.js +128 -0
  81. package/lib/module/policy/redact.js.map +1 -0
  82. package/lib/module/providers/anthropic.js +268 -0
  83. package/lib/module/providers/anthropic.js.map +1 -0
  84. package/lib/module/providers/openai.js +189 -0
  85. package/lib/module/providers/openai.js.map +1 -0
  86. package/lib/module/providers/sse.js +99 -0
  87. package/lib/module/providers/sse.js.map +1 -0
  88. package/lib/module/providers/types.js +4 -0
  89. package/lib/module/providers/types.js.map +1 -0
  90. package/lib/module/session.js +168 -0
  91. package/lib/module/session.js.map +1 -0
  92. package/lib/module/types.js +2 -0
  93. package/lib/module/types.js.map +1 -0
  94. package/lib/typescript/blocks/receipts.d.ts +32 -0
  95. package/lib/typescript/blocks/receipts.d.ts.map +1 -0
  96. package/lib/typescript/blocks/types.d.ts +576 -0
  97. package/lib/typescript/blocks/types.d.ts.map +1 -0
  98. package/lib/typescript/blocks/uiTool.d.ts +15 -0
  99. package/lib/typescript/blocks/uiTool.d.ts.map +1 -0
  100. package/lib/typescript/catalog/catalog.g.d.ts +11 -0
  101. package/lib/typescript/catalog/catalog.g.d.ts.map +1 -0
  102. package/lib/typescript/catalog/snapshotReads.d.ts +37 -0
  103. package/lib/typescript/catalog/snapshotReads.d.ts.map +1 -0
  104. package/lib/typescript/catalog/toProviderTools.d.ts +52 -0
  105. package/lib/typescript/catalog/toProviderTools.d.ts.map +1 -0
  106. package/lib/typescript/catalog/validateParams.d.ts +33 -0
  107. package/lib/typescript/catalog/validateParams.d.ts.map +1 -0
  108. package/lib/typescript/context/buildContextPack.d.ts +32 -0
  109. package/lib/typescript/context/buildContextPack.d.ts.map +1 -0
  110. package/lib/typescript/effects/ledger.d.ts +119 -0
  111. package/lib/typescript/effects/ledger.d.ts.map +1 -0
  112. package/lib/typescript/engine/effectFor.d.ts +21 -0
  113. package/lib/typescript/engine/effectFor.d.ts.map +1 -0
  114. package/lib/typescript/engine/runAgentTurn.d.ts +140 -0
  115. package/lib/typescript/engine/runAgentTurn.d.ts.map +1 -0
  116. package/lib/typescript/engine/systemPrompt.d.ts +49 -0
  117. package/lib/typescript/engine/systemPrompt.d.ts.map +1 -0
  118. package/lib/typescript/index.d.ts +29 -0
  119. package/lib/typescript/index.d.ts.map +1 -0
  120. package/lib/typescript/policy/labels.d.ts +10 -0
  121. package/lib/typescript/policy/labels.d.ts.map +1 -0
  122. package/lib/typescript/policy/policy.d.ts +106 -0
  123. package/lib/typescript/policy/policy.d.ts.map +1 -0
  124. package/lib/typescript/policy/redact.d.ts +37 -0
  125. package/lib/typescript/policy/redact.d.ts.map +1 -0
  126. package/lib/typescript/providers/anthropic.d.ts +22 -0
  127. package/lib/typescript/providers/anthropic.d.ts.map +1 -0
  128. package/lib/typescript/providers/openai.d.ts +19 -0
  129. package/lib/typescript/providers/openai.d.ts.map +1 -0
  130. package/lib/typescript/providers/sse.d.ts +18 -0
  131. package/lib/typescript/providers/sse.d.ts.map +1 -0
  132. package/lib/typescript/providers/types.d.ts +129 -0
  133. package/lib/typescript/providers/types.d.ts.map +1 -0
  134. package/lib/typescript/session.d.ts +58 -0
  135. package/lib/typescript/session.d.ts.map +1 -0
  136. package/lib/typescript/types.d.ts +119 -0
  137. package/lib/typescript/types.d.ts.map +1 -0
  138. package/package.json +58 -0
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Scrub tool results before they leave the device.
3
+ *
4
+ * Two separate reasons, and the second is the one people forget:
5
+ *
6
+ * 1. EGRESS. Tool results go to the customer's own model endpoint. That is
7
+ * their data boundary, not ours — but a response body carrying an
8
+ * `Authorization` header or a Buoy `licenseKey` is a credential, and
9
+ * credentials do not belong in a chat transcript that may be retained for
10
+ * 30 days for abuse monitoring.
11
+ * 2. SELF-INJECTION. Buoy's own network interceptor captures the agent's
12
+ * requests to the model endpoint. Without exclusion, the model reads back
13
+ * its own request headers — including whatever the host app's `headers()`
14
+ * returned — out of `network.getRequests`. That is a credential leak and a
15
+ * prompt-injection channel in one call.
16
+ */
17
+ /**
18
+ * Deep-redact by key name AND by value shape. Depth-limited because tool
19
+ * results can be deeply nested state trees and a runaway walk on a megabyte
20
+ * payload is a frame drop on the JS thread the app is also using.
21
+ */
22
+ export declare function redact(value: unknown, depth?: number): unknown;
23
+ export declare function registerSelfEndpoint(endpoint: string): void;
24
+ export declare function isSelfTraffic(url: unknown): boolean;
25
+ /**
26
+ * Drop the agent's own requests out of a network-shaped result before the
27
+ * model sees them.
28
+ *
29
+ * WALKS INTO OBJECTS, not just top-level arrays. A network reader returns
30
+ * `{ totalCaptured, requests: [...] }`, not a bare array, and a version of
31
+ * this that only handled the bare array quietly did nothing — the agent's own
32
+ * POST to the model endpoint, headers and all, came straight back to it out
33
+ * of the network read. Depth-limited for the same reason `redact` is: this
34
+ * runs on the JS thread the app is drawing on.
35
+ */
36
+ export declare function stripSelfTraffic(value: unknown, depth?: number): unknown;
37
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../../src/policy/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAqDH;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,SAAI,GAAG,OAAO,CAazD;AAQD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQ3D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAOnD;AAQD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,SAAI,GAAG,OAAO,CAYnE"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Anthropic Messages protocol.
3
+ *
4
+ * Four things here are not obvious and each one is a silent failure if missed:
5
+ *
6
+ * 1. `content_block_start` for a `tool_use` carries `"input": {}` — an EMPTY
7
+ * object, never the real arguments. The arguments only exist after
8
+ * concatenating every `input_json_delta.partial_json` and parsing at
9
+ * `content_block_stop`. Reading `.input` at start yields a tool call with no
10
+ * arguments and no error.
11
+ * 2. There is NO `data: [DONE]` sentinel (removed in the 2023-06-01 version).
12
+ * The stream ends at `message_stop`.
13
+ * 3. `error` events arrive MID-STREAM on an already-committed HTTP 200 —
14
+ * `overloaded_error` being the common one. A 200 is not success.
15
+ * 4. Ordering is 400-level strict: `tool_result` blocks must come FIRST in the
16
+ * user content array with any text after, and that user message must
17
+ * immediately follow the assistant turn. "Here are the results:" placed
18
+ * before the blocks is an instant 400.
19
+ */
20
+ import type { Provider, ProviderConfig } from "./types";
21
+ export declare function createAnthropicProvider(config: ProviderConfig): Provider;
22
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAEV,QAAQ,EACR,cAAc,EAKf,MAAM,SAAS,CAAC;AAsCjB,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,CAkLxE"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * OpenAI chat-completions protocol.
3
+ *
4
+ * The differences from Anthropic that actually matter to the code:
5
+ * - Tool results are their own `{role:"tool", tool_call_id, content}` MESSAGE,
6
+ * not blocks inside a user message.
7
+ * - Tool arguments arrive as a JSON STRING, streamed in fragments, and are
8
+ * keyed by an `index` that is stable across deltas while `id`/`name` only
9
+ * appear on the first fragment.
10
+ * - The stream DOES have a `data: [DONE]` sentinel, unlike Anthropic's.
11
+ *
12
+ * This adapter also serves Azure and any OpenAI-compatible org gateway, which
13
+ * is the common shape for an internal LLM proxy. Note Anthropic's own
14
+ * OpenAI-compatibility endpoint is explicitly not production-ready and silently
15
+ * ignores several fields — use the native Anthropic adapter for Anthropic.
16
+ */
17
+ import type { Provider, ProviderConfig } from "./types";
18
+ export declare function createOpenAIProvider(config: ProviderConfig): Provider;
19
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/providers/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAEV,QAAQ,EACR,cAAc,EAGf,MAAM,SAAS,CAAC;AA2CjB,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,CA+GrE"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * SSE reading, with the React Native reality baked in.
3
+ *
4
+ * RN's built-in `fetch` does not implement `response.body`. Under Expo you get
5
+ * a real `ReadableStream` because `expo/fetch` is the global — but
6
+ * `EXPO_PUBLIC_USE_RN_FETCH=1` reverts that, and the bare-RN, NativeScript and
7
+ * TV-CLI lanes never had it. So `readSse` degrades to reading the whole body
8
+ * and replaying it as events rather than failing: a non-streaming answer is a
9
+ * slower chat, while a hard failure is no chat at all.
10
+ */
11
+ export interface SseEvent {
12
+ event?: string;
13
+ data: string;
14
+ }
15
+ export declare function readSse(response: Response): AsyncGenerator<SseEvent, void, void>;
16
+ /** Body text for a failed response, trimmed to something a user can read. */
17
+ export declare function errorBody(response: Response): Promise<string>;
18
+ //# sourceMappingURL=sse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/providers/sse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAsBD,wBAAuB,OAAO,CAC5B,QAAQ,EAAE,QAAQ,GACjB,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAkDtC;AAED,6EAA6E;AAC7E,wBAAsB,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAQnE"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * The provider boundary.
3
+ *
4
+ * Anthropic and OpenAI look similar and are not. Anthropic puts tool results in
5
+ * `tool_result` content blocks inside a USER message and delivers arguments as
6
+ * a parsed object; OpenAI uses a separate `{role:"tool"}` MESSAGE and delivers
7
+ * arguments as a JSON STRING. A single shared "message" type leaks that
8
+ * difference into every caller, so the normalisation happens here: the engine
9
+ * speaks only {@link AgentMessage}, and each adapter owns the reshaping.
10
+ */
11
+ import type { ProviderTool } from "../catalog/toProviderTools";
12
+ /** A tool call the model asked for, normalised across providers. */
13
+ export interface ToolCall {
14
+ /** Provider-assigned id; must be echoed back on the result. */
15
+ id: string;
16
+ /** Provider tool name, e.g. `buoy_storage`. */
17
+ name: string;
18
+ /** Parsed arguments. OpenAI's JSON string is parsed by the adapter. */
19
+ input: Record<string, unknown>;
20
+ }
21
+ export interface ToolResult {
22
+ toolCallId: string;
23
+ /** Already JSON-encoded and truncated by the engine. */
24
+ content: string;
25
+ isError?: boolean;
26
+ }
27
+ export type AgentMessage = {
28
+ role: "user";
29
+ text: string;
30
+ } | {
31
+ role: "assistant";
32
+ text: string;
33
+ toolCalls?: ToolCall[];
34
+ } | {
35
+ role: "tool-results";
36
+ results: ToolResult[];
37
+ };
38
+ /** Incremental output from a streaming turn. */
39
+ export type StreamEvent = {
40
+ type: "text";
41
+ delta: string;
42
+ } | {
43
+ type: "tool-call";
44
+ call: ToolCall;
45
+ }
46
+ /** Mid-stream provider error. Anthropic can emit these on a committed 200. */
47
+ | {
48
+ type: "error";
49
+ message: string;
50
+ } | {
51
+ type: "done";
52
+ stopReason?: string;
53
+ usage?: TokenUsage;
54
+ };
55
+ export interface TokenUsage {
56
+ input: number;
57
+ output: number;
58
+ /**
59
+ * Anthropic's prompt-cache counters, when the provider reports them.
60
+ * `cacheRead` is the prefix that was served from cache at 0.1x — the whole
61
+ * point of caching — and `cacheWrite` is the prefix stored at 1.25x on the
62
+ * request that populated it. Both are reported SEPARATELY from `input` by
63
+ * the API, so a cached request shows a tiny `input` and a large `cacheRead`
64
+ * rather than a smaller `input`; adding them is what gives the real total.
65
+ */
66
+ cacheRead?: number;
67
+ cacheWrite?: number;
68
+ }
69
+ export interface ProviderRequest {
70
+ messages: AgentMessage[];
71
+ system: string;
72
+ tools: ProviderTool[];
73
+ model: string;
74
+ maxTokens: number;
75
+ signal?: AbortSignal;
76
+ }
77
+ export interface ProviderConfig {
78
+ /** The org's gateway, or the provider's own URL for the dev-only direct mode. */
79
+ endpoint: string;
80
+ /**
81
+ * Fresh headers per request, so short-lived tokens from the host app's own
82
+ * session work. This is why Buoy stores no credential of its own.
83
+ */
84
+ headers?: () => Record<string, string> | Promise<Record<string, string>>;
85
+ /** Dev-only direct mode. Never for a distributed build. */
86
+ apiKey?: string;
87
+ model: string;
88
+ maxTokens?: number;
89
+ /** Anthropic API version header. Ignored by the OpenAI adapter. */
90
+ anthropicVersion?: string;
91
+ /**
92
+ * Ask Anthropic to cache the unchanging prefix of every request — the tool
93
+ * definitions and the system prompt. Default true; ignored by the OpenAI
94
+ * adapter, which caches automatically with no annotation.
95
+ *
96
+ * WHY IT IS ON BY DEFAULT. That prefix is ~20k tokens (24 tools, 192
97
+ * actions) and is byte-identical on every request of every turn, and a turn
98
+ * re-sends it once per tool round-trip: a four-tool answer paid for it five
99
+ * times. A cache write costs 1.25x and a read costs 0.1x, so anything past
100
+ * the first request is a ~90% saving on the largest part of the bill.
101
+ *
102
+ * The one case where this LOSES is a turn that calls no tools and is never
103
+ * followed by another within the cache's 5-minute window — one request that
104
+ * pays the write multiplier and never reads. That is not what a devtools
105
+ * chat session looks like, which is why the default is on rather than off.
106
+ *
107
+ * Set false for a gateway that rejects unknown `cache_control` fields.
108
+ */
109
+ cache?: boolean;
110
+ /**
111
+ * Extra fields merged into every request BODY, last — `temperature`, a
112
+ * gateway's routing hints, whatever the endpoint demands that this config
113
+ * doesn't model. The escape hatch that keeps one config type honest across
114
+ * every OpenAI-compatible gateway; core fields (model, messages, tools,
115
+ * stream) win only if you don't override them, so use with care.
116
+ */
117
+ requestOverrides?: Record<string, unknown>;
118
+ }
119
+ export interface Provider {
120
+ readonly protocol: "anthropic" | "openai";
121
+ /**
122
+ * Run one request. Yields incrementally when the platform supports it and
123
+ * falls back to a single buffered chunk when it does not — React Native's
124
+ * built-in fetch has no `response.body`, so streaming only exists where
125
+ * `expo/fetch` is the global.
126
+ */
127
+ send(req: ProviderRequest): AsyncGenerator<StreamEvent, void, void>;
128
+ }
129
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/providers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,oEAAoE;AACpE,MAAM,WAAW,QAAQ;IACvB,+DAA+D;IAC/D,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,UAAU,EAAE,CAAA;CAAE,CAAC;AAEpD,gDAAgD;AAChD,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE;AACvC,8EAA8E;GAC5E;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,UAAU,CAAA;CAAE,CAAC;AAE9D,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC1C;;;;;OAKG;IACH,IAAI,CAAC,GAAG,EAAE,eAAe,GAAG,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;CACrE"}
@@ -0,0 +1,58 @@
1
+ import { type TurnEvent } from "./engine/runAgentTurn";
2
+ import { type ContextPack } from "./engine/systemPrompt";
3
+ import { EffectLedger } from "./effects/ledger";
4
+ import type { AgentMessage, ProviderConfig } from "./providers/types";
5
+ import { type AskBuoyPolicy } from "./policy/policy";
6
+ import type { DispatchFn, SnapshotFn, ToolDescriptor } from "./types";
7
+ export interface AskBuoySessionConfig extends ProviderConfig {
8
+ protocol: "anthropic" | "openai";
9
+ dispatch: DispatchFn;
10
+ /**
11
+ * Reads a tool's `getSnapshot`. Without it the console, network, route and
12
+ * env reads are unavailable — they are snapshot-only, not actions.
13
+ */
14
+ readSnapshot?: SnapshotFn;
15
+ /**
16
+ * From `listToolActions()` — the live truth about this device, with
17
+ * `getSnapshot` appended for tools whose adapter publishes one.
18
+ */
19
+ availableActions: Record<string, string[]>;
20
+ policy?: AskBuoyPolicy;
21
+ context?: ContextPack;
22
+ /** `__DEV__ === false` for this bundle. */
23
+ isRelease: boolean;
24
+ appName?: string;
25
+ platform?: string;
26
+ /** Override the built-in catalog. Tests and the desktop port use this. */
27
+ catalog?: ToolDescriptor[];
28
+ requestApproval?: RunApproval;
29
+ }
30
+ type RunApproval = (input: {
31
+ id: string;
32
+ toolId: string;
33
+ action: string;
34
+ label: string;
35
+ description: string;
36
+ reason: string;
37
+ }) => Promise<boolean>;
38
+ export interface AskBuoySession {
39
+ readonly ledger: EffectLedger;
40
+ readonly messages: AgentMessage[];
41
+ /** Probe the app for grounding. Safe to call more than once. */
42
+ prime(): Promise<void>;
43
+ /**
44
+ * Re-point the session at the tools this device currently exposes.
45
+ *
46
+ * The live tool list is NOT session identity: packages register a frame or
47
+ * two apart, so it legitimately changes right after open. Rebuilding the
48
+ * session when it does threw away the conversation, the model's memory and
49
+ * the undo ledger mid-chat — silently, because the transcript lives in a
50
+ * separate store and kept rendering. Update in place instead.
51
+ */
52
+ setAvailableActions(actions: Record<string, string[]>): void;
53
+ send(text: string, signal?: AbortSignal): AsyncGenerator<TurnEvent, void, void>;
54
+ reset(): void;
55
+ }
56
+ export declare function createAskBuoySession(config: AskBuoySessionConfig): AskBuoySession;
57
+ export {};
58
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"AAWA,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,KAAK,EAAE,YAAY,EAAY,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE7E,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEtE,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,QAAQ,EAAE,WAAW,GAAG,QAAQ,CAAC;IACjC,QAAQ,EAAE,UAAU,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,2CAA2C;IAC3C,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3B,eAAe,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,KAAK,WAAW,GAAG,CAAC,KAAK,EAAE;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEvB,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,CAAC;IAClC,gEAAgE;IAChE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB;;;;;;;;OAQG;IACH,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;IAC7D,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,cAAc,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAChF,KAAK,IAAI,IAAI,CAAC;CACf;AAsCD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,cAAc,CAqHjF"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * The vocabulary Ask Buoy needs and Buoy's wire protocol does not have.
3
+ *
4
+ * The device advertises `ToolCapability { toolId, version, actions: string[] }`
5
+ * — names only. Nothing on the wire, and nothing in `toolActionRegistry`, says
6
+ * what an action's params look like, whether calling it changes anything, or
7
+ * whether it still works once `__DEV__` is false. The MCP server papers over
8
+ * that with ~48 hand-written zod shapes, but those live in a Node-only package
9
+ * and cover a fraction of the ~179 actions.
10
+ *
11
+ * This module is that missing description, as plain data, so an agent can be
12
+ * told the truth about a tool before it calls one.
13
+ */
14
+ /**
15
+ * A JSON Schema subset: object/string/number/boolean/array + enum + required.
16
+ * Deliberately not the whole spec — `validateParams` implements exactly this
17
+ * much, and a schema the validator cannot check is worse than no schema.
18
+ */
19
+ export interface JsonSchema {
20
+ type?: "object" | "string" | "number" | "integer" | "boolean" | "array" | "null";
21
+ description?: string;
22
+ enum?: (string | number | boolean | null)[];
23
+ properties?: Record<string, JsonSchema>;
24
+ required?: string[];
25
+ additionalProperties?: boolean;
26
+ items?: JsonSchema;
27
+ default?: unknown;
28
+ /** Union of primitive shapes, for the few params that genuinely take either. */
29
+ anyOf?: JsonSchema[];
30
+ /** Tuple bounds — `storage.async.multiSet` takes [key, value] pairs. */
31
+ minItems?: number;
32
+ maxItems?: number;
33
+ }
34
+ /**
35
+ * What calling this action does to the app.
36
+ *
37
+ * `destructive` is deliberately broad: anything that wipes, clears, resets,
38
+ * replaces a whole store, reloads the realm, or starts impersonating a real
39
+ * person. When the classification is arguable, the catalog rounds UP — the
40
+ * cost of an over-cautious label is a confirmation the user didn't need; the
41
+ * cost of an under-cautious one is a tester's device state gone.
42
+ */
43
+ export type ActionEffect = "read" | "write" | "destructive";
44
+ /**
45
+ * What this action does in a RELEASE build (`__DEV__ === false`).
46
+ *
47
+ * This field exists because several Buoy actions REPORT SUCCESS AND DO NOTHING
48
+ * once `__DEV__` is false, and an agent that relays that success to a QA tester
49
+ * causes a bug report filed against data that was never applied. Two live
50
+ * examples: `network.upsertOverrideRule` persists a rule the engine will never
51
+ * consult (`network/overrides/engine.ts:74`), and every fiber-walking action
52
+ * returns empty because React Native installs `__REACT_DEVTOOLS_GLOBAL_HOOK__`
53
+ * only under `if (__DEV__)` — no Buoy code ever installs it, so no amount of
54
+ * configuration brings those back.
55
+ */
56
+ export type ReleaseBehavior =
57
+ /** Behaves the same in dev and release. */
58
+ "works"
59
+ /** Returns a success result and has no effect. The dangerous one. */
60
+ | "noop"
61
+ /** Succeeds but the data is always empty. */
62
+ | "empty"
63
+ /** Raises an error, which at least is honest. */
64
+ | "throws"
65
+ /** Not established. Treated as `noop` by the policy layer — fail closed. */
66
+ | "unknown";
67
+ /** How to reverse an action, when it can be reversed at all. */
68
+ export interface UndoSpec {
69
+ /** The action on the same tool that reverses this one. */
70
+ action: string;
71
+ /** How to build the undo params from the original call's params/result. */
72
+ note: string;
73
+ }
74
+ export interface ActionDescriptor {
75
+ /** Exact key in the adapter's `actions` object. Never a display name. */
76
+ action: string;
77
+ /** One line, written to help a model choose between sibling actions. */
78
+ summary: string;
79
+ /** Gotchas, defaults, and what the result looks like. */
80
+ description?: string;
81
+ params: JsonSchema;
82
+ effect: ActionEffect;
83
+ release: ReleaseBehavior;
84
+ /** For non-`works` release behaviour: the evidence and the reason. */
85
+ releaseNote?: string;
86
+ /**
87
+ * Host-app prerequisites this action needs beyond the package being
88
+ * installed — `expo-router`, `<RouteTracker/>` mounted,
89
+ * `createImpersonateTool({onSearchUsers})`, a TV platform. An action name
90
+ * appearing in `listToolActions()` does NOT mean it can do anything here.
91
+ */
92
+ requires?: string[];
93
+ undo?: UndoSpec;
94
+ /**
95
+ * True when the tool's store only records while something holds a
96
+ * subscription. A cold read then returns an empty timeline, and the honest
97
+ * answer is "nothing is holding capture open", never "nothing happened".
98
+ */
99
+ armsCapture?: boolean;
100
+ }
101
+ export interface ToolDescriptor {
102
+ /** The sync tool id — `query`, `route-events`, `time-machine`, … */
103
+ toolId: string;
104
+ title: string;
105
+ /** 1-3 sentences telling a model what this tool is for. */
106
+ summary: string;
107
+ /** When the whole tool is absent or inert on a device. */
108
+ unavailableWhen?: string;
109
+ actions: ActionDescriptor[];
110
+ }
111
+ /** The one function `agent-core` needs from its host to actually do anything. */
112
+ export type DispatchFn = (toolId: string, action: string, params?: unknown) => Promise<unknown>;
113
+ /**
114
+ * Read a tool's `getSnapshot` — the half of Buoy's read surface that is not an
115
+ * action. See `catalog/snapshotReads.ts`; without it the agent cannot see the
116
+ * console, network traffic, routes or env at all.
117
+ */
118
+ export type SnapshotFn = (toolId: string) => Promise<unknown>;
119
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gFAAgF;IAChF,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;AAE5D;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe;AACzB,2CAA2C;AACzC,OAAO;AACT,qEAAqE;GACnE,MAAM;AACR,6CAA6C;GAC3C,OAAO;AACT,iDAAiD;GAC/C,QAAQ;AACV,4EAA4E;GAC1E,SAAS,CAAC;AAEd,gEAAgE;AAChE,MAAM,WAAW,QAAQ;IACvB,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,eAAe,CAAC;IACzB,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED,iFAAiF;AACjF,MAAM,MAAM,UAAU,GAAG,CACvB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,OAAO,KACb,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@buoy-gg/agent-core",
3
+ "version": "7.0.33",
4
+ "description": "Headless agent core for Ask Buoy - the tool catalog, BYO-model providers, turn loop and effect ledger that let an LLM drive Buoy devtools",
5
+ "main": "lib/commonjs/index.js",
6
+ "module": "lib/module/index.js",
7
+ "types": "lib/typescript/index.d.ts",
8
+ "react-native": "lib/module/index.js",
9
+ "source": "src/index.ts",
10
+ "files": [
11
+ "lib"
12
+ ],
13
+ "keywords": [
14
+ "react-native",
15
+ "devtools",
16
+ "ai",
17
+ "agent",
18
+ "llm",
19
+ "buoy"
20
+ ],
21
+ "devDependencies": {
22
+ "typescript": "~5.8.3"
23
+ },
24
+ "react-native-builder-bob": {
25
+ "source": "src",
26
+ "output": "lib",
27
+ "targets": [
28
+ "commonjs",
29
+ "module",
30
+ [
31
+ "typescript",
32
+ {
33
+ "project": "tsconfig.build.json"
34
+ }
35
+ ]
36
+ ]
37
+ },
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/LovesWorking/react-native-buoy.git",
41
+ "directory": "packages/agent-core"
42
+ },
43
+ "bugs": {
44
+ "url": "https://github.com/LovesWorking/react-native-buoy/issues"
45
+ },
46
+ "homepage": "https://github.com/LovesWorking/react-native-buoy/tree/main/packages/agent-core#readme",
47
+ "publishConfig": {
48
+ "access": "public",
49
+ "tag": "latest"
50
+ },
51
+ "scripts": {
52
+ "build": "bob build",
53
+ "typecheck": "tsc --noEmit",
54
+ "clean": "rimraf lib",
55
+ "test": "pnpm run typecheck",
56
+ "postinstall": "echo \"Run pnpm build to compile this package\""
57
+ }
58
+ }