@rubytech/create-realagent 1.0.707 → 1.0.709

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 (48) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/oauth-llm/dist/index.d.ts +101 -0
  3. package/payload/platform/lib/oauth-llm/dist/index.d.ts.map +1 -0
  4. package/payload/platform/lib/oauth-llm/dist/index.js +353 -0
  5. package/payload/platform/lib/oauth-llm/dist/index.js.map +1 -0
  6. package/payload/platform/lib/oauth-llm/src/index.ts +526 -0
  7. package/payload/platform/lib/oauth-llm/tsconfig.json +8 -0
  8. package/payload/platform/neo4j/schema.cypher +37 -11
  9. package/payload/platform/package.json +2 -2
  10. package/payload/platform/plugins/admin/mcp/dist/index.js +9 -9
  11. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  12. package/payload/platform/plugins/admin/skills/business-profile/SKILL.md +1 -1
  13. package/payload/platform/plugins/admin/skills/onboarding/SKILL.md +5 -10
  14. package/payload/platform/plugins/email/mcp/dist/lib/screening.d.ts +3 -3
  15. package/payload/platform/plugins/email/mcp/dist/lib/screening.d.ts.map +1 -1
  16. package/payload/platform/plugins/email/mcp/dist/lib/screening.js +12 -12
  17. package/payload/platform/plugins/email/mcp/dist/lib/screening.js.map +1 -1
  18. package/payload/platform/plugins/email/mcp/dist/scripts/email-auto-respond.js +14 -28
  19. package/payload/platform/plugins/email/mcp/dist/scripts/email-auto-respond.js.map +1 -1
  20. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js +9 -19
  21. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js.map +1 -1
  22. package/payload/platform/plugins/memory/mcp/dist/index.js +46 -18
  23. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  24. package/payload/platform/plugins/memory/mcp/dist/lib/document-hierarchy.d.ts.map +1 -1
  25. package/payload/platform/plugins/memory/mcp/dist/lib/document-hierarchy.js +22 -18
  26. package/payload/platform/plugins/memory/mcp/dist/lib/document-hierarchy.js.map +1 -1
  27. package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.js +4 -4
  28. package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.js.map +1 -1
  29. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts +98 -24
  30. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts.map +1 -1
  31. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js +176 -86
  32. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js.map +1 -1
  33. package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.d.ts.map +1 -1
  34. package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.js +12 -46
  35. package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.js.map +1 -1
  36. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.d.ts.map +1 -1
  37. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.js +24 -12
  38. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.js.map +1 -1
  39. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts +27 -11
  40. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
  41. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +276 -238
  42. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
  43. package/payload/platform/plugins/memory/references/schema-base.md +67 -15
  44. package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +53 -20
  45. package/payload/platform/templates/specialists/agents/database-operator.md +18 -0
  46. package/payload/server/chunk-Y57ACANQ.js +12292 -0
  47. package/payload/server/maxy-edge.js +1 -1
  48. package/payload/server/server.js +25 -44
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-realagent",
3
- "version": "1.0.707",
3
+ "version": "1.0.709",
4
4
  "description": "Install Real Agent — Built for agents. By agents.",
5
5
  "bin": {
6
6
  "create-realagent": "./dist/index.js"
@@ -0,0 +1,101 @@
1
+ /**
2
+ * OAuth-bearer LLM calls for admin-side classifiers (Task 740).
3
+ *
4
+ * Every admin-side classifier (memory-classify, memory-rank, commitment,
5
+ * adherence, inbound-gateway, query classifier, summarisation, email
6
+ * screening) uses Claude Code OAuth credentials — never the Anthropic
7
+ * API key. The API-key path is reserved for the public agent.
8
+ *
9
+ * Mechanism: read the access token from ~/.claude/.credentials.json,
10
+ * refresh it via the standard refresh-token grant if expired, then call
11
+ * api.anthropic.com with `Authorization: Bearer <token>` and the
12
+ * `anthropic-beta: oauth-2025-04-20` header. Billed against the operator's
13
+ * Claude Code subscription, not the API-key key. Refresh uses a
14
+ * module-level mutex so concurrent classifier calls during expiry don't
15
+ * race and invalidate each other's tokens (Anthropic rotates both tokens
16
+ * on refresh).
17
+ *
18
+ * Implementation note: this lib uses raw fetch() rather than the
19
+ * @anthropic-ai/sdk package to keep the lib dependency-free — every
20
+ * consumer already has its own SDK copy for other purposes, but the
21
+ * shared lib would create a circular package dependency. The Messages
22
+ * API surface we use (model + system + one user message + max_tokens)
23
+ * is small and stable.
24
+ *
25
+ * Failure modes are surfaced as a structured `Result` so callers can
26
+ * pattern-match without parsing error strings. The skill / agent layer
27
+ * is responsible for translating `fallback` results into operator-visible
28
+ * blocker messages (loud failure doctrine — Task 540, 740).
29
+ */
30
+ declare const OAUTH_BETA_HEADER = "oauth-2025-04-20";
31
+ /** Anthropic tool definition — structural-output enforcement via function calling. */
32
+ export interface OauthLlmTool {
33
+ name: string;
34
+ description: string;
35
+ input_schema: Record<string, unknown>;
36
+ }
37
+ export interface CallOauthLlmParams {
38
+ /** Anthropic model id (e.g. claude-haiku-4-5). */
39
+ model: string;
40
+ /** System prompt — the classifier instructions. */
41
+ system: string;
42
+ /** User message — the input to classify / rank / etc. */
43
+ userMessage: string;
44
+ /** Max output tokens. Default 4096. */
45
+ maxTokens?: number;
46
+ /** Hard timeout in ms for the model call. Default 60_000. */
47
+ timeoutMs?: number;
48
+ /**
49
+ * Optional tools for structured output. When provided with a forced
50
+ * `toolChoiceName`, the model returns a `tool_use` block whose `input` is
51
+ * a structured object matching the tool's `input_schema` — strictly typed
52
+ * JSON without the parsing brittleness of free-form text output.
53
+ */
54
+ tools?: OauthLlmTool[];
55
+ /** Force the model to call this tool. Required when `tools` is provided. */
56
+ toolChoiceName?: string;
57
+ }
58
+ /** Result when the call did not declare any tool — only text or fallback. */
59
+ export type CallOauthLlmTextResult = {
60
+ kind: "ok";
61
+ text: string;
62
+ } | CallOauthLlmFallback;
63
+ /** Result when the call forced a tool — only the tool input or fallback. */
64
+ export type CallOauthLlmToolResult = {
65
+ kind: "ok-tool";
66
+ toolName: string;
67
+ input: Record<string, unknown>;
68
+ } | CallOauthLlmFallback;
69
+ /** Discriminated union of every possible result. Returned by the no-overload form. */
70
+ export type CallOauthLlmResult = CallOauthLlmTextResult | CallOauthLlmToolResult;
71
+ export interface CallOauthLlmFallback {
72
+ kind: "fallback";
73
+ /** Human-readable single-line reason (for operator-visible blocker). */
74
+ reason: string;
75
+ /** Stable classifier — callers can pattern-match for retry/abort policy. */
76
+ cause: "missing-creds" | "dead-token" | "refresh-failed" | "auth-error" | "rate-limit" | "server-error" | "network-error" | "timeout" | "empty-response" | "malformed-response" | "unexpected";
77
+ }
78
+ /**
79
+ * Call an Anthropic model via OAuth bearer auth.
80
+ *
81
+ * Returns:
82
+ * { kind: "ok", text } — model's text response
83
+ * { kind: "ok-tool", toolName, input } — when `tools` + `toolChoiceName` provided
84
+ * { kind: "fallback", reason, cause } — caller decides whether to abort
85
+ *
86
+ * The caller is responsible for translating fallback results into
87
+ * operator-visible blocker messages — this wrapper never silently
88
+ * substitutes a degraded response.
89
+ *
90
+ * Overloads narrow the return type by call shape: text-only callers (no
91
+ * `tools`) statically rule out `ok-tool`; tool callers statically rule out
92
+ * `ok`. Mixed callers get the full union.
93
+ */
94
+ export declare function callOauthLlm(params: Omit<CallOauthLlmParams, "tools" | "toolChoiceName">): Promise<CallOauthLlmTextResult>;
95
+ export declare function callOauthLlm(params: CallOauthLlmParams & {
96
+ tools: OauthLlmTool[];
97
+ toolChoiceName: string;
98
+ }): Promise<CallOauthLlmToolResult>;
99
+ export declare function callOauthLlm(params: CallOauthLlmParams): Promise<CallOauthLlmResult>;
100
+ export { OAUTH_BETA_HEADER };
101
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAgBH,QAAA,MAAM,iBAAiB,qBAAqB,CAAC;AAe7C,sFAAsF;AACtF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,6EAA6E;AAC7E,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5B,oBAAoB,CAAC;AAEzB,4EAA4E;AAC5E,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACrE,oBAAoB,CAAC;AAEzB,sFAAsF;AACtF,MAAM,MAAM,kBAAkB,GAAG,sBAAsB,GAAG,sBAAsB,CAAC;AAEjF,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,UAAU,CAAC;IACjB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,KAAK,EACD,eAAe,GACf,YAAY,GACZ,gBAAgB,GAChB,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,eAAe,GACf,SAAS,GACT,gBAAgB,GAChB,oBAAoB,GACpB,YAAY,CAAC;CAClB;AAuND;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,OAAO,GAAG,gBAAgB,CAAC,GAC3D,OAAO,CAAC,sBAAsB,CAAC,CAAC;AACnC,wBAAgB,YAAY,CAC1B,MAAM,EAAE,kBAAkB,GAAG;IAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAC7E,OAAO,CAAC,sBAAsB,CAAC,CAAC;AACnC,wBAAgB,YAAY,CAC1B,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAwK/B,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,353 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth-bearer LLM calls for admin-side classifiers (Task 740).
4
+ *
5
+ * Every admin-side classifier (memory-classify, memory-rank, commitment,
6
+ * adherence, inbound-gateway, query classifier, summarisation, email
7
+ * screening) uses Claude Code OAuth credentials — never the Anthropic
8
+ * API key. The API-key path is reserved for the public agent.
9
+ *
10
+ * Mechanism: read the access token from ~/.claude/.credentials.json,
11
+ * refresh it via the standard refresh-token grant if expired, then call
12
+ * api.anthropic.com with `Authorization: Bearer <token>` and the
13
+ * `anthropic-beta: oauth-2025-04-20` header. Billed against the operator's
14
+ * Claude Code subscription, not the API-key key. Refresh uses a
15
+ * module-level mutex so concurrent classifier calls during expiry don't
16
+ * race and invalidate each other's tokens (Anthropic rotates both tokens
17
+ * on refresh).
18
+ *
19
+ * Implementation note: this lib uses raw fetch() rather than the
20
+ * @anthropic-ai/sdk package to keep the lib dependency-free — every
21
+ * consumer already has its own SDK copy for other purposes, but the
22
+ * shared lib would create a circular package dependency. The Messages
23
+ * API surface we use (model + system + one user message + max_tokens)
24
+ * is small and stable.
25
+ *
26
+ * Failure modes are surfaced as a structured `Result` so callers can
27
+ * pattern-match without parsing error strings. The skill / agent layer
28
+ * is responsible for translating `fallback` results into operator-visible
29
+ * blocker messages (loud failure doctrine — Task 540, 740).
30
+ */
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.OAUTH_BETA_HEADER = void 0;
33
+ exports.callOauthLlm = callOauthLlm;
34
+ const node_fs_1 = require("node:fs");
35
+ const node_path_1 = require("node:path");
36
+ const node_os_1 = require("node:os");
37
+ // ---------------------------------------------------------------------------
38
+ // Constants — token endpoint, client id, beta header, file path.
39
+ // All four are pinned values that match the Claude Code CLI's own usage.
40
+ // ---------------------------------------------------------------------------
41
+ const CREDENTIALS_FILE = (0, node_path_1.resolve)((0, node_os_1.homedir)(), ".claude", ".credentials.json");
42
+ const TOKEN_ENDPOINT = "https://platform.claude.com/v1/oauth/token";
43
+ const ANTHROPIC_MESSAGES_ENDPOINT = "https://api.anthropic.com/v1/messages";
44
+ const ANTHROPIC_VERSION = "2023-06-01";
45
+ const CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
46
+ const OAUTH_BETA_HEADER = "oauth-2025-04-20";
47
+ exports.OAUTH_BETA_HEADER = OAUTH_BETA_HEADER;
48
+ /** Refresh proactively when the token expires within this window. */
49
+ const EXPIRING_THRESHOLD_MS = 5 * 60 * 1000;
50
+ // ---------------------------------------------------------------------------
51
+ // Credential reading + refresh — minimal duplicate of platform/ui claude-auth.
52
+ // We duplicate (not import) so this lib stays self-contained and importable
53
+ // from MCP plugins via dist/. The duplicated logic is small and the auth
54
+ // mechanism is pinned by Anthropic — divergence risk is low.
55
+ // ---------------------------------------------------------------------------
56
+ function readCredentials() {
57
+ let raw;
58
+ try {
59
+ raw = (0, node_fs_1.readFileSync)(CREDENTIALS_FILE, "utf-8");
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ let data;
65
+ try {
66
+ data = JSON.parse(raw);
67
+ }
68
+ catch {
69
+ return null;
70
+ }
71
+ const oauth = data.claudeAiOauth;
72
+ if (!oauth || typeof oauth !== "object")
73
+ return null;
74
+ const accessToken = oauth.accessToken;
75
+ const refreshToken = oauth.refreshToken;
76
+ const expiresAt = oauth.expiresAt;
77
+ if (typeof accessToken !== "string" || !accessToken)
78
+ return null;
79
+ if (typeof expiresAt !== "number" || !Number.isFinite(expiresAt) || expiresAt <= 0) {
80
+ return null;
81
+ }
82
+ return {
83
+ accessToken,
84
+ refreshToken: typeof refreshToken === "string" && refreshToken ? refreshToken : null,
85
+ expiresAt,
86
+ };
87
+ }
88
+ function writeCredentials(tokens) {
89
+ const newExpiresAt = typeof tokens.expiresIn === "number" && tokens.expiresIn > 0
90
+ ? Date.now() + tokens.expiresIn * 1000
91
+ : Date.now() + 3600 * 1000;
92
+ let fileData = {};
93
+ try {
94
+ fileData = JSON.parse((0, node_fs_1.readFileSync)(CREDENTIALS_FILE, "utf-8"));
95
+ }
96
+ catch {
97
+ // start fresh
98
+ }
99
+ const existing = fileData.claudeAiOauth;
100
+ fileData.claudeAiOauth = {
101
+ ...existing,
102
+ accessToken: tokens.accessToken,
103
+ ...(tokens.refreshToken != null ? { refreshToken: tokens.refreshToken } : {}),
104
+ expiresAt: newExpiresAt,
105
+ };
106
+ (0, node_fs_1.writeFileSync)(CREDENTIALS_FILE, JSON.stringify(fileData, null, 2), "utf-8");
107
+ return newExpiresAt;
108
+ }
109
+ // Module-level mutex serialises refresh calls. Anthropic rotates both
110
+ // tokens on refresh; concurrent unsynchronised refreshes invalidate
111
+ // each other.
112
+ let refreshLock = null;
113
+ async function refreshAccessToken(current) {
114
+ if (refreshLock)
115
+ return refreshLock;
116
+ refreshLock = (async () => {
117
+ // Re-read inside the lock — another caller may have refreshed already.
118
+ const fresh = readCredentials();
119
+ if (fresh && fresh.expiresAt - Date.now() > EXPIRING_THRESHOLD_MS) {
120
+ return fresh;
121
+ }
122
+ if (!current.refreshToken) {
123
+ return null;
124
+ }
125
+ let res;
126
+ try {
127
+ res = await fetch(TOKEN_ENDPOINT, {
128
+ method: "POST",
129
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
130
+ body: new URLSearchParams({
131
+ grant_type: "refresh_token",
132
+ refresh_token: current.refreshToken,
133
+ client_id: CLIENT_ID,
134
+ }),
135
+ });
136
+ }
137
+ catch (err) {
138
+ const msg = err instanceof Error ? err.message : String(err);
139
+ console.error(`[oauth-llm] refresh network error: ${msg}`);
140
+ return null;
141
+ }
142
+ if (!res.ok) {
143
+ const body = await res.text().catch(() => "");
144
+ console.error(`[oauth-llm] refresh failed status=${res.status} body=${body.slice(0, 200)}`);
145
+ return null;
146
+ }
147
+ let tokenData;
148
+ try {
149
+ tokenData = (await res.json());
150
+ }
151
+ catch {
152
+ console.error("[oauth-llm] refresh returned malformed JSON");
153
+ return null;
154
+ }
155
+ const newAccessToken = tokenData.access_token;
156
+ const newRefreshToken = tokenData.refresh_token;
157
+ const expiresIn = tokenData.expires_in;
158
+ if (typeof newAccessToken !== "string" || !newAccessToken) {
159
+ console.error("[oauth-llm] refresh response missing access_token");
160
+ return null;
161
+ }
162
+ const newExpiresAt = writeCredentials({
163
+ accessToken: newAccessToken,
164
+ refreshToken: typeof newRefreshToken === "string" && newRefreshToken
165
+ ? newRefreshToken
166
+ : current.refreshToken,
167
+ expiresIn: typeof expiresIn === "number" && expiresIn > 0 ? expiresIn : undefined,
168
+ });
169
+ console.error(`[oauth-llm] refresh ok expiresAt=${new Date(newExpiresAt).toISOString()}`);
170
+ return {
171
+ accessToken: newAccessToken,
172
+ refreshToken: typeof newRefreshToken === "string" && newRefreshToken
173
+ ? newRefreshToken
174
+ : current.refreshToken,
175
+ expiresAt: newExpiresAt,
176
+ };
177
+ })();
178
+ try {
179
+ return await refreshLock;
180
+ }
181
+ finally {
182
+ refreshLock = null;
183
+ }
184
+ }
185
+ /**
186
+ * Read credentials and proactively refresh if approaching expiry.
187
+ * Returns null when the credentials are missing or unrecoverable
188
+ * (operator must re-authenticate via Claude Code login).
189
+ */
190
+ async function ensureValidToken() {
191
+ const creds = readCredentials();
192
+ if (!creds)
193
+ return null;
194
+ const remaining = creds.expiresAt - Date.now();
195
+ if (remaining > EXPIRING_THRESHOLD_MS)
196
+ return creds;
197
+ if (remaining > 0 && !creds.refreshToken)
198
+ return creds; // valid but no way to renew
199
+ if (remaining <= 0 && !creds.refreshToken)
200
+ return null; // dead
201
+ return refreshAccessToken(creds);
202
+ }
203
+ // ---------------------------------------------------------------------------
204
+ // First-call beta-header diagnostic — emitted once per process so server.log
205
+ // makes the OAuth path visible without flooding on every classifier call.
206
+ // ---------------------------------------------------------------------------
207
+ let betaHeaderLogged = false;
208
+ function logBetaHeaderOnce() {
209
+ if (betaHeaderLogged)
210
+ return;
211
+ betaHeaderLogged = true;
212
+ console.error(`[oauth-llm] beta-header=${OAUTH_BETA_HEADER}`);
213
+ }
214
+ async function callOauthLlm(params) {
215
+ const { model, system, userMessage, maxTokens = 4096, timeoutMs = 60_000, tools, toolChoiceName, } = params;
216
+ if (tools && tools.length > 0 && !toolChoiceName) {
217
+ return {
218
+ kind: "fallback",
219
+ cause: "unexpected",
220
+ reason: "callOauthLlm: `tools` provided without `toolChoiceName`. Forced tool selection is required.",
221
+ };
222
+ }
223
+ logBetaHeaderOnce();
224
+ const creds = await ensureValidToken();
225
+ if (!creds) {
226
+ return {
227
+ kind: "fallback",
228
+ cause: "missing-creds",
229
+ reason: "Claude Code OAuth credentials missing or expired with no refresh token available — operator must re-authenticate.",
230
+ };
231
+ }
232
+ const controller = new AbortController();
233
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
234
+ let res;
235
+ try {
236
+ res = await fetch(ANTHROPIC_MESSAGES_ENDPOINT, {
237
+ method: "POST",
238
+ headers: {
239
+ "Content-Type": "application/json",
240
+ "anthropic-version": ANTHROPIC_VERSION,
241
+ "anthropic-beta": OAUTH_BETA_HEADER,
242
+ Authorization: `Bearer ${creds.accessToken}`,
243
+ },
244
+ body: JSON.stringify({
245
+ model,
246
+ max_tokens: maxTokens,
247
+ system,
248
+ messages: [{ role: "user", content: userMessage }],
249
+ ...(tools && tools.length > 0 ? { tools } : {}),
250
+ ...(toolChoiceName
251
+ ? { tool_choice: { type: "tool", name: toolChoiceName } }
252
+ : {}),
253
+ }),
254
+ signal: controller.signal,
255
+ });
256
+ }
257
+ catch (err) {
258
+ clearTimeout(timer);
259
+ const msg = err instanceof Error ? err.message : String(err);
260
+ if (controller.signal.aborted) {
261
+ return {
262
+ kind: "fallback",
263
+ cause: "timeout",
264
+ reason: `Model call timed out after ${timeoutMs}ms.`,
265
+ };
266
+ }
267
+ return {
268
+ kind: "fallback",
269
+ cause: "network-error",
270
+ reason: `Network error reaching Anthropic: ${msg}`,
271
+ };
272
+ }
273
+ clearTimeout(timer);
274
+ if (!res.ok) {
275
+ const body = await res.text().catch(() => "");
276
+ if (res.status === 401 || res.status === 403) {
277
+ return {
278
+ kind: "fallback",
279
+ cause: "auth-error",
280
+ reason: `OAuth bearer rejected (status=${res.status}) — token may be revoked or beta header rejected. body=${body.slice(0, 200)}`,
281
+ };
282
+ }
283
+ if (res.status === 429) {
284
+ return {
285
+ kind: "fallback",
286
+ cause: "rate-limit",
287
+ reason: `Anthropic rate limit hit (status=429): ${body.slice(0, 200)}`,
288
+ };
289
+ }
290
+ if (res.status >= 500) {
291
+ return {
292
+ kind: "fallback",
293
+ cause: "server-error",
294
+ reason: `Anthropic server error (status=${res.status}): ${body.slice(0, 200)}`,
295
+ };
296
+ }
297
+ return {
298
+ kind: "fallback",
299
+ cause: "unexpected",
300
+ reason: `Anthropic returned status=${res.status}: ${body.slice(0, 200)}`,
301
+ };
302
+ }
303
+ let payload;
304
+ try {
305
+ payload = (await res.json());
306
+ }
307
+ catch {
308
+ return {
309
+ kind: "fallback",
310
+ cause: "malformed-response",
311
+ reason: "Anthropic returned malformed JSON.",
312
+ };
313
+ }
314
+ if (payload.error) {
315
+ return {
316
+ kind: "fallback",
317
+ cause: "unexpected",
318
+ reason: `Anthropic API error: ${payload.error.type ?? "unknown"} ${payload.error.message ?? ""}`,
319
+ };
320
+ }
321
+ // When the caller forced a tool, prefer the tool_use block — its input
322
+ // is the structured output the caller wants.
323
+ if (toolChoiceName) {
324
+ const toolBlock = payload.content?.find((block) => block.type === "tool_use");
325
+ if (!toolBlock || !toolBlock.input || typeof toolBlock.input !== "object") {
326
+ return {
327
+ kind: "fallback",
328
+ cause: "empty-response",
329
+ reason: "Model returned no tool_use block despite forced tool selection.",
330
+ };
331
+ }
332
+ return {
333
+ kind: "ok-tool",
334
+ toolName: toolBlock.name ?? toolChoiceName,
335
+ input: toolBlock.input,
336
+ };
337
+ }
338
+ const textBlock = payload.content?.find((block) => {
339
+ if (block.type !== "text")
340
+ return false;
341
+ const candidate = block.text;
342
+ return typeof candidate === "string" && candidate.trim().length > 0;
343
+ });
344
+ if (!textBlock) {
345
+ return {
346
+ kind: "fallback",
347
+ cause: "empty-response",
348
+ reason: "Model returned no text content.",
349
+ };
350
+ }
351
+ return { kind: "ok", text: textBlock.text };
352
+ }
353
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}