@frihet/mcp-server 1.17.0 → 2.0.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/README.md +84 -59
- package/dist/agent-onboarding.d.ts +1 -1
- package/dist/agent-onboarding.js +3 -3
- package/dist/canary/mcp-harness.d.ts +1 -1
- package/dist/canary/mcp-harness.js +4 -1
- package/dist/capability-truth.js +20 -12
- package/dist/claude-candidate-contract.d.ts +482 -0
- package/dist/claude-candidate-contract.js +87 -0
- package/dist/claude-output-privacy.d.ts +17 -0
- package/dist/claude-output-privacy.js +240 -0
- package/dist/claude-profile.d.ts +18 -0
- package/dist/claude-profile.js +260 -0
- package/dist/client-interface.d.ts +26 -20
- package/dist/client.d.ts +65 -29
- package/dist/client.js +278 -167
- package/dist/demo-client.d.ts +27 -21
- package/dist/demo-client.js +31 -14
- package/dist/deposit-contract.d.ts +29 -0
- package/dist/deposit-contract.js +76 -0
- package/dist/fetch-no-redirect.d.ts +3 -0
- package/dist/fetch-no-redirect.js +16 -0
- package/dist/fiscal-aliases.d.ts +2 -2
- package/dist/fiscal-aliases.js +2 -2
- package/dist/fiscal-period.d.ts +26 -0
- package/dist/fiscal-period.js +31 -0
- package/dist/google-profile.d.ts +19 -0
- package/dist/google-profile.js +122 -0
- package/dist/index.js +31 -7
- package/dist/logger.d.ts +1 -1
- package/dist/logger.js +2 -2
- package/dist/muse-profile.d.ts +19 -0
- package/dist/muse-profile.js +122 -0
- package/dist/observability.js +3 -2
- package/dist/openai-profile.d.ts +2 -2
- package/dist/openai-profile.js +37 -11
- package/dist/openai-review-contract.d.ts +1 -1
- package/dist/openai-review-contract.js +4 -5
- package/dist/openai-review-oauth.d.ts +107 -7
- package/dist/openai-review-oauth.js +161 -17
- package/dist/prompts/register-all.js +32 -78
- package/dist/redaction.d.ts +5 -0
- package/dist/redaction.js +9 -0
- package/dist/resources/register-all.js +150 -54
- package/dist/retry-after.d.ts +19 -0
- package/dist/retry-after.js +84 -0
- package/dist/server-composition.d.ts +5 -2
- package/dist/server-composition.js +35 -5
- package/dist/tool-exposure.d.ts +6 -5
- package/dist/tool-exposure.js +15 -13
- package/dist/tools/audit_gl.js +8 -8
- package/dist/tools/backend-availability.d.ts +8 -29
- package/dist/tools/backend-availability.js +31 -30
- package/dist/tools/bank_rules.js +66 -15
- package/dist/tools/banking.js +5 -13
- package/dist/tools/clients.js +252 -6
- package/dist/tools/deposits.js +107 -97
- package/dist/tools/einvoice.d.ts +17 -3
- package/dist/tools/einvoice.js +59 -12
- package/dist/tools/fiscal.d.ts +3 -4
- package/dist/tools/fiscal.js +93 -60
- package/dist/tools/gestoria.js +15 -7
- package/dist/tools/hr.js +41 -11
- package/dist/tools/igic.d.ts +9 -8
- package/dist/tools/igic.js +34 -64
- package/dist/tools/impuesto_sociedades.d.ts +4 -5
- package/dist/tools/impuesto_sociedades.js +16 -37
- package/dist/tools/intelligence.js +164 -10
- package/dist/tools/invoices.js +109 -42
- package/dist/tools/kitchen.js +19 -9
- package/dist/tools/quotes.js +86 -25
- package/dist/tools/recurring.js +26 -25
- package/dist/tools/register-all.d.ts +2 -2
- package/dist/tools/register-all.js +9 -6
- package/dist/tools/search.d.ts +19 -0
- package/dist/tools/search.js +84 -0
- package/dist/tools/shared.d.ts +17 -37
- package/dist/tools/shared.js +96 -30
- package/dist/tools/team.js +8 -16
- package/dist/tools/time.js +4 -12
- package/dist/tools/vendors.js +240 -6
- package/dist/types.d.ts +3 -1
- package/dist/workflows/daily-operational-brief.d.ts +163 -0
- package/dist/workflows/daily-operational-brief.js +881 -0
- package/docs/agent-onboarding.json +15 -5
- package/package.json +26 -12
- package/dist/tools/onboarding.d.ts +0 -19
- package/dist/tools/onboarding.js +0 -64
package/dist/demo-client.d.ts
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import type { IFrihetClient } from "./client-interface.js";
|
|
21
21
|
import type { CreateWebhookInput, CreateWebhookResult, PaginatedResponse, UpdateWebhookInput, Webhook } from "./types.js";
|
|
22
|
-
import type
|
|
22
|
+
import { type BinaryDocument, type EInvoiceDocument, type EInvoiceExportResult, type McpEInvoiceExportFormat } from "./client.js";
|
|
23
23
|
type Rec = Record<string, unknown>;
|
|
24
24
|
export declare class DemoFrihetClient implements IFrihetClient {
|
|
25
25
|
listInvoices(params?: {
|
|
@@ -99,6 +99,21 @@ export declare class DemoFrihetClient implements IFrihetClient {
|
|
|
99
99
|
createWebhook(data: CreateWebhookInput): Promise<CreateWebhookResult>;
|
|
100
100
|
updateWebhook(id: string, data: UpdateWebhookInput): Promise<Webhook>;
|
|
101
101
|
deleteWebhook(_id: string): Promise<void>;
|
|
102
|
+
globalSearch(params: {
|
|
103
|
+
q: string;
|
|
104
|
+
types?: ReadonlyArray<"invoices" | "expenses" | "vendors" | "clients" | "products">;
|
|
105
|
+
limit?: number;
|
|
106
|
+
offset?: number;
|
|
107
|
+
}): Promise<{
|
|
108
|
+
data: Record<string, unknown>[];
|
|
109
|
+
total: number;
|
|
110
|
+
limit: number;
|
|
111
|
+
offset: number;
|
|
112
|
+
hasMore: boolean;
|
|
113
|
+
query: string;
|
|
114
|
+
types: ReadonlyArray<"invoices" | "expenses" | "vendors" | "clients" | "products">;
|
|
115
|
+
truncated?: boolean;
|
|
116
|
+
}>;
|
|
102
117
|
listClientContacts(_clientId: string, params?: {
|
|
103
118
|
limit?: number;
|
|
104
119
|
offset?: number;
|
|
@@ -173,14 +188,9 @@ export declare class DemoFrihetClient implements IFrihetClient {
|
|
|
173
188
|
}>;
|
|
174
189
|
exportEInvoice(params: {
|
|
175
190
|
invoiceId: string;
|
|
176
|
-
format:
|
|
191
|
+
format: McpEInvoiceExportFormat;
|
|
177
192
|
signed?: boolean;
|
|
178
|
-
}): Promise<
|
|
179
|
-
xmlUrl: string;
|
|
180
|
-
filename: string;
|
|
181
|
-
format: string;
|
|
182
|
-
signed: boolean;
|
|
183
|
-
}>;
|
|
193
|
+
}): Promise<EInvoiceExportResult>;
|
|
184
194
|
faceSubmit(params: {
|
|
185
195
|
invoiceId: string;
|
|
186
196
|
mode: "mock" | "sandbox" | "production";
|
|
@@ -314,7 +324,7 @@ export declare class DemoFrihetClient implements IFrihetClient {
|
|
|
314
324
|
updateTeamMemberRole(memberId: string, role: string): Promise<Rec>;
|
|
315
325
|
removeTeamMember(_memberId: string): Promise<void>;
|
|
316
326
|
approveGLEntry(entryId: string, notes?: string): Promise<Rec>;
|
|
317
|
-
rejectGLEntry(entryId: string,
|
|
327
|
+
rejectGLEntry(entryId: string, note: string): Promise<Rec>;
|
|
318
328
|
getGLEntryAuditLog(entryId: string): Promise<Rec>;
|
|
319
329
|
addCustomPortalDomain(data: {
|
|
320
330
|
domain: string;
|
|
@@ -355,15 +365,13 @@ export declare class DemoFrihetClient implements IFrihetClient {
|
|
|
355
365
|
}): Promise<PaginatedResponse<Rec>>;
|
|
356
366
|
createBankRule(data: {
|
|
357
367
|
name: string;
|
|
358
|
-
|
|
368
|
+
bankConditions: Array<{
|
|
359
369
|
field: string;
|
|
360
370
|
operator: string;
|
|
361
371
|
value: string;
|
|
362
372
|
}>;
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
value: string;
|
|
366
|
-
}>;
|
|
373
|
+
action: string;
|
|
374
|
+
actionConfig: Record<string, unknown>;
|
|
367
375
|
isActive?: boolean;
|
|
368
376
|
}): Promise<Rec>;
|
|
369
377
|
sendGestoriaMessage(data: {
|
|
@@ -406,7 +414,9 @@ export declare class DemoFrihetClient implements IFrihetClient {
|
|
|
406
414
|
};
|
|
407
415
|
}): Promise<Rec>;
|
|
408
416
|
getGestoriaAgingConsolidated(_params?: {
|
|
409
|
-
|
|
417
|
+
workspaceIds?: string[];
|
|
418
|
+
asOf?: string;
|
|
419
|
+
bustCache?: boolean;
|
|
410
420
|
}): Promise<Rec>;
|
|
411
421
|
listLeaves(params?: {
|
|
412
422
|
limit?: number;
|
|
@@ -430,8 +440,8 @@ export declare class DemoFrihetClient implements IFrihetClient {
|
|
|
430
440
|
employeeId: string;
|
|
431
441
|
mood?: string;
|
|
432
442
|
location?: string;
|
|
433
|
-
}): Promise<Rec>;
|
|
434
|
-
attendanceClockOut(entryId: string): Promise<Rec>;
|
|
443
|
+
}, _idempotencyKey?: string): Promise<Rec>;
|
|
444
|
+
attendanceClockOut(entryId: string, _idempotencyKey?: string): Promise<Rec>;
|
|
435
445
|
getOvertimeReport(params: {
|
|
436
446
|
period: string;
|
|
437
447
|
employeeId?: string;
|
|
@@ -450,10 +460,6 @@ export declare class DemoFrihetClient implements IFrihetClient {
|
|
|
450
460
|
getPayrollChecklist(params: {
|
|
451
461
|
month: string;
|
|
452
462
|
}): Promise<Rec>;
|
|
453
|
-
getOnboardingStatus(): Promise<Rec>;
|
|
454
|
-
setOnboardingPersona(data: {
|
|
455
|
-
persona: "autonomo" | "empresa" | "agencia" | "gestoria";
|
|
456
|
-
}): Promise<Rec>;
|
|
457
463
|
getPermissionsMatrix(): Promise<Rec>;
|
|
458
464
|
getMyPermissions(): Promise<Rec>;
|
|
459
465
|
getCurrentPeriod(params?: {
|
package/dist/demo-client.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* - delete / remove methods → resolve void (interface return type forbids a
|
|
18
18
|
* stamp; this is the one accepted, documented gap).
|
|
19
19
|
*/
|
|
20
|
+
import { toApiEInvoiceExportFormat, } from "./client.js";
|
|
20
21
|
import { Buffer } from "node:buffer";
|
|
21
22
|
import { READ_STAMP, FISCAL_STAMP, DEMO_NOW, demoPage, demoEmptyPage, findOrStub, demoId, simulateWrite, simulateAction, demoClients, demoProducts, demoInvoices, demoExpenses, demoQuotes, demoVendors, demoBankAccounts, demoTransactions, } from "./demo-fixtures.js";
|
|
22
23
|
const DEMO_RBAC_ROLES = ["owner", "admin", "manager", "sales", "accountant", "employee", "viewer"];
|
|
@@ -299,6 +300,20 @@ export class DemoFrihetClient {
|
|
|
299
300
|
async deleteWebhook(_id) {
|
|
300
301
|
return;
|
|
301
302
|
}
|
|
303
|
+
// ---------------------------------------------------------------- Cross-resource search
|
|
304
|
+
// ----------------------------------------------------------------
|
|
305
|
+
async globalSearch(params) {
|
|
306
|
+
return {
|
|
307
|
+
data: [],
|
|
308
|
+
total: 0,
|
|
309
|
+
limit: params.limit ?? 25,
|
|
310
|
+
offset: params.offset ?? 0,
|
|
311
|
+
hasMore: false,
|
|
312
|
+
query: params.q,
|
|
313
|
+
types: params.types ?? ["invoices", "expenses", "vendors", "clients", "products"],
|
|
314
|
+
truncated: false,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
302
317
|
// ---------------------------------------------------------------- CRM: Contacts
|
|
303
318
|
async listClientContacts(_clientId, params) {
|
|
304
319
|
return demoEmptyPage(params);
|
|
@@ -426,7 +441,15 @@ export class DemoFrihetClient {
|
|
|
426
441
|
return { fileUrl: "https://app.frihet.io/demo/datev.csv", filename: "demo-datev.csv", rowCount: 24, fiscalPeriod: `${params.periodStart}..${params.periodEnd}`, encoding: "cp1252", ...FISCAL_STAMP };
|
|
427
442
|
}
|
|
428
443
|
async exportEInvoice(params) {
|
|
429
|
-
|
|
444
|
+
const format = toApiEInvoiceExportFormat(params.format);
|
|
445
|
+
return {
|
|
446
|
+
xml: `<?xml version="1.0" encoding="UTF-8"?><DemoEInvoice format="${format}"/>`,
|
|
447
|
+
contentType: "application/xml",
|
|
448
|
+
filename: `${params.invoiceId}.xml`,
|
|
449
|
+
format,
|
|
450
|
+
signed: params.signed ?? false,
|
|
451
|
+
...FISCAL_STAMP,
|
|
452
|
+
};
|
|
430
453
|
}
|
|
431
454
|
async faceSubmit(params) {
|
|
432
455
|
return { registroFACe: "DEMO-FACE-0001", status: "submitted", submittedAt: DEMO_NOW, mode: params.mode, ...FISCAL_STAMP };
|
|
@@ -503,7 +526,8 @@ export class DemoFrihetClient {
|
|
|
503
526
|
}
|
|
504
527
|
// ---------------------------------------------------------------- Fiscal (simulated / read summaries)
|
|
505
528
|
async getFiscalModeloSummary(modeloCode, period) {
|
|
506
|
-
|
|
529
|
+
const defaultPeriod = modeloCode === "390" || modeloCode === "347" ? "2026" : "2026-Q2";
|
|
530
|
+
return { model: modeloCode, period: period ?? defaultPeriod, readonly: true, summary: { totalRevenue: 3960.4, totalExpenses: 405.6 }, ...FISCAL_STAMP };
|
|
507
531
|
}
|
|
508
532
|
async getVerifactuStatus(invoiceId) {
|
|
509
533
|
return { invoiceId, status: "accepted", accepted: true, submittedAt: DEMO_NOW, ...FISCAL_STAMP };
|
|
@@ -575,8 +599,8 @@ export class DemoFrihetClient {
|
|
|
575
599
|
async approveGLEntry(entryId, notes) {
|
|
576
600
|
return simulateAction(entryId, { status: "approved", ...(notes ? { notes } : {}) });
|
|
577
601
|
}
|
|
578
|
-
async rejectGLEntry(entryId,
|
|
579
|
-
return simulateAction(entryId, { status: "rejected",
|
|
602
|
+
async rejectGLEntry(entryId, note) {
|
|
603
|
+
return simulateAction(entryId, { status: "rejected", note });
|
|
580
604
|
}
|
|
581
605
|
async getGLEntryAuditLog(entryId) {
|
|
582
606
|
return { entryId, log: [], ...READ_STAMP };
|
|
@@ -614,7 +638,7 @@ export class DemoFrihetClient {
|
|
|
614
638
|
return demoEmptyPage(params);
|
|
615
639
|
}
|
|
616
640
|
async createBankRule(data) {
|
|
617
|
-
return simulateWrite("demo_rule", { name: data.name,
|
|
641
|
+
return simulateWrite("demo_rule", { name: data.name, bankConditions: data.bankConditions, action: data.action, actionConfig: data.actionConfig }, { isActive: data.isActive ?? true });
|
|
618
642
|
}
|
|
619
643
|
// ---------------------------------------------------------------- Gestoria
|
|
620
644
|
async sendGestoriaMessage(data) {
|
|
@@ -648,10 +672,10 @@ export class DemoFrihetClient {
|
|
|
648
672
|
async cancelLeave(leaveId) {
|
|
649
673
|
return simulateAction(leaveId, { status: "cancelled" });
|
|
650
674
|
}
|
|
651
|
-
async attendanceClockIn(data) {
|
|
675
|
+
async attendanceClockIn(data, _idempotencyKey) {
|
|
652
676
|
return simulateWrite("demo_att", { employeeId: data.employeeId, ...(data.mood ? { mood: data.mood } : {}), ...(data.location ? { location: data.location } : {}) }, { status: "open", clockInAt: DEMO_NOW });
|
|
653
677
|
}
|
|
654
|
-
async attendanceClockOut(entryId) {
|
|
678
|
+
async attendanceClockOut(entryId, _idempotencyKey) {
|
|
655
679
|
return simulateAction(entryId, { status: "closed", clockOutAt: DEMO_NOW });
|
|
656
680
|
}
|
|
657
681
|
async getOvertimeReport(params) {
|
|
@@ -692,13 +716,6 @@ export class DemoFrihetClient {
|
|
|
692
716
|
...READ_STAMP,
|
|
693
717
|
};
|
|
694
718
|
}
|
|
695
|
-
// ---------------------------------------------------------------- Onboarding
|
|
696
|
-
async getOnboardingStatus() {
|
|
697
|
-
return { workspaceId: "demo_ws_001", persona: "autonomo", completedSteps: ["profile"], pendingSteps: ["bank", "invoice"], percentComplete: 33, startedAt: DEMO_NOW, ...READ_STAMP };
|
|
698
|
-
}
|
|
699
|
-
async setOnboardingPersona(data) {
|
|
700
|
-
return { workspaceId: "demo_ws_001", persona: data.persona, updatedAt: DEMO_NOW, ...READ_STAMP };
|
|
701
|
-
}
|
|
702
719
|
// ---------------------------------------------------------------- Permissions
|
|
703
720
|
async getPermissionsMatrix() {
|
|
704
721
|
return {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
/** Locally generated guidance only: never includes input values or provider text. */
|
|
3
|
+
export declare class DepositInputError extends Error {
|
|
4
|
+
readonly statusCode = 400;
|
|
5
|
+
readonly errorCode = "invalid_deposit_input";
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
/** Writable fields accepted by publicApi v132's strict deposits schema. */
|
|
9
|
+
export declare const depositFields: {
|
|
10
|
+
clientId: z.ZodString;
|
|
11
|
+
clientName: z.ZodString;
|
|
12
|
+
amount: z.ZodNumber;
|
|
13
|
+
currency: z.ZodString;
|
|
14
|
+
description: z.ZodString;
|
|
15
|
+
receivedDate: z.ZodString;
|
|
16
|
+
paymentMethod: z.ZodOptional<z.ZodString>;
|
|
17
|
+
paymentReference: z.ZodOptional<z.ZodString>;
|
|
18
|
+
};
|
|
19
|
+
/** Writable fields accepted by publicApi v132's strict /deposits/:id/apply schema. */
|
|
20
|
+
export declare const applyDepositFields: {
|
|
21
|
+
invoiceId: z.ZodString;
|
|
22
|
+
invoiceNumber: z.ZodString;
|
|
23
|
+
amount: z.ZodNumber;
|
|
24
|
+
};
|
|
25
|
+
/** Validate deposit application payload against the strict backend contract before request I/O. */
|
|
26
|
+
export declare function normalizeApplyDepositBody(input?: Record<string, unknown>): Record<string, unknown>;
|
|
27
|
+
/** Preserve the established MCP date/reference names on the canonical API wire. */
|
|
28
|
+
export declare function normalizeDepositBody(input: Record<string, unknown>, partial: boolean): Record<string, unknown>;
|
|
29
|
+
//# sourceMappingURL=deposit-contract.d.ts.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
/** Locally generated guidance only: never includes input values or provider text. */
|
|
3
|
+
export class DepositInputError extends Error {
|
|
4
|
+
statusCode = 400;
|
|
5
|
+
errorCode = "invalid_deposit_input";
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "DepositInputError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** Writable fields accepted by publicApi v132's strict deposits schema. */
|
|
12
|
+
export const depositFields = {
|
|
13
|
+
clientId: z.string().min(1).max(128),
|
|
14
|
+
clientName: z.string().min(1).max(500),
|
|
15
|
+
amount: z.number().positive(),
|
|
16
|
+
currency: z.string().length(3),
|
|
17
|
+
description: z.string().min(1).max(2000),
|
|
18
|
+
receivedDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
|
|
19
|
+
paymentMethod: z.string().max(200).optional(),
|
|
20
|
+
paymentReference: z.string().max(200).optional(),
|
|
21
|
+
};
|
|
22
|
+
/** Writable fields accepted by publicApi v132's strict /deposits/:id/apply schema. */
|
|
23
|
+
export const applyDepositFields = {
|
|
24
|
+
invoiceId: z.string().min(1).max(128),
|
|
25
|
+
invoiceNumber: z.string().min(1).max(200),
|
|
26
|
+
amount: z.number().positive(),
|
|
27
|
+
};
|
|
28
|
+
const applyDepositBody = z.object(applyDepositFields).strict();
|
|
29
|
+
/** Validate deposit application payload against the strict backend contract before request I/O. */
|
|
30
|
+
export function normalizeApplyDepositBody(input = {}) {
|
|
31
|
+
if (Object.prototype.hasOwnProperty.call(input, "notes")) {
|
|
32
|
+
throw new DepositInputError("Deposit application field 'notes' is not writable; the API does not accept it. / El campo 'notes' no se puede guardar al aplicar el depósito.");
|
|
33
|
+
}
|
|
34
|
+
const parsed = applyDepositBody.safeParse(input);
|
|
35
|
+
if (!parsed.success) {
|
|
36
|
+
const known = new Set(Object.keys(applyDepositFields));
|
|
37
|
+
const fields = [...new Set(parsed.error.issues.map((issue) => issue.path[0]).filter((field) => typeof field === "string" && known.has(field)))];
|
|
38
|
+
throw new DepositInputError(`Invalid deposit application input${fields.length ? ` (${fields.join(", ")})` : ""}. Provide invoiceId, invoiceNumber and a positive amount. / Indica invoiceId, invoiceNumber y un importe positivo.`);
|
|
39
|
+
}
|
|
40
|
+
return parsed.data;
|
|
41
|
+
}
|
|
42
|
+
const createDepositBody = z.object({
|
|
43
|
+
...depositFields,
|
|
44
|
+
currency: depositFields.currency.default("EUR"),
|
|
45
|
+
}).strict();
|
|
46
|
+
// PATCH must not inject the create default or turn an empty update into a write.
|
|
47
|
+
const updateDepositBody = z.object(depositFields).partial().strict().refine((fields) => Object.values(fields).some((value) => value !== undefined), { message: "Provide at least one writable deposit field / Indica al menos un campo del depósito" });
|
|
48
|
+
/** Preserve the established MCP date/reference names on the canonical API wire. */
|
|
49
|
+
export function normalizeDepositBody(input, partial) {
|
|
50
|
+
const body = { ...input };
|
|
51
|
+
for (const unsupported of ["status", "notes"]) {
|
|
52
|
+
if (Object.prototype.hasOwnProperty.call(body, unsupported)) {
|
|
53
|
+
throw new DepositInputError(`Deposit field '${unsupported}' is not writable; the API does not accept it. / El campo '${unsupported}' no se puede guardar en el depósito.`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
for (const [alias, canonical] of [["date", "receivedDate"], ["reference", "paymentReference"]]) {
|
|
57
|
+
if (body[alias] !== undefined) {
|
|
58
|
+
if (body[canonical] !== undefined && body[canonical] !== body[alias]) {
|
|
59
|
+
throw new DepositInputError(`Conflicting deposit fields '${alias}' and '${canonical}'. / Los campos '${alias}' y '${canonical}' no coinciden.`);
|
|
60
|
+
}
|
|
61
|
+
body[canonical] = body[alias];
|
|
62
|
+
}
|
|
63
|
+
delete body[alias];
|
|
64
|
+
}
|
|
65
|
+
const parsed = (partial ? updateDepositBody : createDepositBody).safeParse(body);
|
|
66
|
+
if (!parsed.success) {
|
|
67
|
+
const known = new Set(Object.keys(depositFields));
|
|
68
|
+
const fields = [...new Set(parsed.error.issues.map((issue) => issue.path[0]).filter((field) => typeof field === "string" && known.has(field)))];
|
|
69
|
+
const guidance = partial
|
|
70
|
+
? "Provide at least one valid writable deposit field; date uses YYYY-MM-DD. / Indica al menos un campo editable válido; date usa YYYY-MM-DD."
|
|
71
|
+
: "Provide clientId, clientName, a positive amount, description and receivedDate (date) in YYYY-MM-DD format. / Indica clientId, clientName, un importe positivo, description y receivedDate (date) con formato YYYY-MM-DD.";
|
|
72
|
+
throw new DepositInputError(`Invalid deposit input${fields.length ? ` (${fields.join(", ")})` : ""}. ${guidance}`);
|
|
73
|
+
}
|
|
74
|
+
return parsed.data;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=deposit-contract.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
|
|
2
|
+
/** Validate a manual-mode fetch response without owning any network authority. */
|
|
3
|
+
export async function rejectRedirectResponse(response) {
|
|
4
|
+
if (REDIRECT_STATUSES.has(response.status)) {
|
|
5
|
+
try {
|
|
6
|
+
await response.body?.cancel();
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
/* Best effort; still reject. */
|
|
10
|
+
}
|
|
11
|
+
// Never include Location, URL, headers or body in the error.
|
|
12
|
+
throw new TypeError("Redirect responses are not allowed");
|
|
13
|
+
}
|
|
14
|
+
return response;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=fetch-no-redirect.js.map
|
package/dist/fiscal-aliases.d.ts
CHANGED
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
* pointing an alias key at the SAME registered-tool object makes it callable
|
|
19
19
|
* with zero duplication and zero drift risk.
|
|
20
20
|
*
|
|
21
|
-
* This intentionally does NOT touch `src/tools/*.ts` (where the
|
|
21
|
+
* This intentionally does NOT touch `src/tools/*.ts` (where the 158-tool
|
|
22
22
|
* audit / pin tests count literal `registerTool(` call sites) and is applied
|
|
23
23
|
* to the REAL `McpServer` instance only, AFTER `registerAllTools()` — the
|
|
24
24
|
* `tool-exposure.test.ts` / `openai-*.test.ts` suites exercise
|
|
25
25
|
* `registerAllTools()` against a bare `StubMcpServer` and never call
|
|
26
|
-
* `applyFiscalAliases`, so the
|
|
26
|
+
* `applyFiscalAliases`, so the 158-tool pins are untouched by design.
|
|
27
27
|
*
|
|
28
28
|
* KNOWN LIMITATION: this relies on the SDK's internal (unprefixed-by-type,
|
|
29
29
|
* but underscore-private) `_registeredTools` field. It is FAIL-OPEN — if a
|
package/dist/fiscal-aliases.js
CHANGED
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
* pointing an alias key at the SAME registered-tool object makes it callable
|
|
19
19
|
* with zero duplication and zero drift risk.
|
|
20
20
|
*
|
|
21
|
-
* This intentionally does NOT touch `src/tools/*.ts` (where the
|
|
21
|
+
* This intentionally does NOT touch `src/tools/*.ts` (where the 158-tool
|
|
22
22
|
* audit / pin tests count literal `registerTool(` call sites) and is applied
|
|
23
23
|
* to the REAL `McpServer` instance only, AFTER `registerAllTools()` — the
|
|
24
24
|
* `tool-exposure.test.ts` / `openai-*.test.ts` suites exercise
|
|
25
25
|
* `registerAllTools()` against a bare `StubMcpServer` and never call
|
|
26
|
-
* `applyFiscalAliases`, so the
|
|
26
|
+
* `applyFiscalAliases`, so the 158-tool pins are untouched by design.
|
|
27
27
|
*
|
|
28
28
|
* KNOWN LIMITATION: this relies on the SDK's internal (unprefixed-by-type,
|
|
29
29
|
* but underscore-private) `_registeredTools` field. It is FAIL-OPEN — if a
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Period contract for the READ-ONLY fiscal modelo summaries.
|
|
3
|
+
*
|
|
4
|
+
* Single source for BOTH the client (which query param to send) and the tools
|
|
5
|
+
* (what to validate before calling, what to compare after). Mirrors the
|
|
6
|
+
* deployed Frihet-ERP backend (functions/src/publicApi.ts):
|
|
7
|
+
* - 303/130 read `?quarter=YYYY-Q[1-4]`, default current quarter
|
|
8
|
+
* - 390 reads `?year=YYYY`, default current year
|
|
9
|
+
* - 347 reads `?year=YYYY`, default current year
|
|
10
|
+
* Every other modelo code has no backend route (404 "Unknown fiscal model").
|
|
11
|
+
* The backend silently answers the CURRENT period for any param it does not
|
|
12
|
+
* read, so the param name here is load-bearing.
|
|
13
|
+
*/
|
|
14
|
+
export interface FiscalPeriodRule {
|
|
15
|
+
/** Query param the backend reads. */
|
|
16
|
+
param: "quarter" | "year";
|
|
17
|
+
pattern: RegExp;
|
|
18
|
+
format: string;
|
|
19
|
+
}
|
|
20
|
+
export declare const FISCAL_PERIOD_RULES: Readonly<Record<string, FiscalPeriodRule>>;
|
|
21
|
+
/**
|
|
22
|
+
* Query object for GET /fiscal/modelo/{code}. Throws for a modelo code without
|
|
23
|
+
* a backend rule so no caller can fall back to an ignored `?period=` param.
|
|
24
|
+
*/
|
|
25
|
+
export declare function fiscalModeloQuery(modeloCode: string, period?: string): Record<string, string | undefined>;
|
|
26
|
+
//# sourceMappingURL=fiscal-period.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Period contract for the READ-ONLY fiscal modelo summaries.
|
|
3
|
+
*
|
|
4
|
+
* Single source for BOTH the client (which query param to send) and the tools
|
|
5
|
+
* (what to validate before calling, what to compare after). Mirrors the
|
|
6
|
+
* deployed Frihet-ERP backend (functions/src/publicApi.ts):
|
|
7
|
+
* - 303/130 read `?quarter=YYYY-Q[1-4]`, default current quarter
|
|
8
|
+
* - 390 reads `?year=YYYY`, default current year
|
|
9
|
+
* - 347 reads `?year=YYYY`, default current year
|
|
10
|
+
* Every other modelo code has no backend route (404 "Unknown fiscal model").
|
|
11
|
+
* The backend silently answers the CURRENT period for any param it does not
|
|
12
|
+
* read, so the param name here is load-bearing.
|
|
13
|
+
*/
|
|
14
|
+
export const FISCAL_PERIOD_RULES = {
|
|
15
|
+
"303": { param: "quarter", pattern: /^\d{4}-Q[1-4]$/, format: "YYYY-Q1..YYYY-Q4" },
|
|
16
|
+
"130": { param: "quarter", pattern: /^\d{4}-Q[1-4]$/, format: "YYYY-Q1..YYYY-Q4" },
|
|
17
|
+
"390": { param: "year", pattern: /^\d{4}$/, format: "YYYY" },
|
|
18
|
+
"347": { param: "year", pattern: /^\d{4}$/, format: "YYYY" },
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Query object for GET /fiscal/modelo/{code}. Throws for a modelo code without
|
|
22
|
+
* a backend rule so no caller can fall back to an ignored `?period=` param.
|
|
23
|
+
*/
|
|
24
|
+
export function fiscalModeloQuery(modeloCode, period) {
|
|
25
|
+
const rule = FISCAL_PERIOD_RULES[modeloCode];
|
|
26
|
+
if (!rule) {
|
|
27
|
+
throw new Error(`No deployed fiscal summary backend for Modelo ${modeloCode}`);
|
|
28
|
+
}
|
|
29
|
+
return { [rule.param]: period };
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=fiscal-period.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google Connected Apps Profile for the Frihet MCP Server.
|
|
3
|
+
*
|
|
4
|
+
* Implements the curated 18-tool financial management surface submitted
|
|
5
|
+
* for the Google Connected Apps Platform Developer Preview (Gemini app & Google Search).
|
|
6
|
+
*
|
|
7
|
+
* Requirements:
|
|
8
|
+
* - Curated catalogue: 18 high-value small business & freelancer tools.
|
|
9
|
+
* - Human-in-the-loop: Invoices and financial documents are created strictly in draft status.
|
|
10
|
+
* - Zero unconfirmed destructive actions (no direct AEAT / VeriFactu fiscal submissions).
|
|
11
|
+
* - Standard output redaction for sensitive fields.
|
|
12
|
+
*/
|
|
13
|
+
export declare const GOOGLE_CANDIDATE_TOOLS: ReadonlySet<string>;
|
|
14
|
+
export declare const GOOGLE_CANDIDATE_TOOL_COUNT: number;
|
|
15
|
+
export declare const GOOGLE_INSTRUCTIONS = "Frihet ERP \u2014 natural-language business and financial management for Google Connected Apps (Gemini & Search).\nUse get_business_context for complete company health and plan limits.\nQuery and review invoices, expenses, quotes, clients, and products with pagination.\nAll created invoices are drafts. Confirm parameters with the user before creating records.";
|
|
16
|
+
export declare function googleToolResult(result: unknown): unknown;
|
|
17
|
+
export declare const GOOGLE_FORCED_INPUT_VALUES: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
|
|
18
|
+
export declare function applyGoogleProfile(server: any): void;
|
|
19
|
+
//# sourceMappingURL=google-profile.d.ts.map
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google Connected Apps Profile for the Frihet MCP Server.
|
|
3
|
+
*
|
|
4
|
+
* Implements the curated 18-tool financial management surface submitted
|
|
5
|
+
* for the Google Connected Apps Platform Developer Preview (Gemini app & Google Search).
|
|
6
|
+
*
|
|
7
|
+
* Requirements:
|
|
8
|
+
* - Curated catalogue: 18 high-value small business & freelancer tools.
|
|
9
|
+
* - Human-in-the-loop: Invoices and financial documents are created strictly in draft status.
|
|
10
|
+
* - Zero unconfirmed destructive actions (no direct AEAT / VeriFactu fiscal submissions).
|
|
11
|
+
* - Standard output redaction for sensitive fields.
|
|
12
|
+
*/
|
|
13
|
+
import { deepRedact, redactText } from "./redaction.js";
|
|
14
|
+
export const GOOGLE_CANDIDATE_TOOLS = new Set([
|
|
15
|
+
"get_business_context",
|
|
16
|
+
"get_monthly_summary",
|
|
17
|
+
"get_quarterly_taxes",
|
|
18
|
+
"list_invoices",
|
|
19
|
+
"get_invoice",
|
|
20
|
+
"search_invoices",
|
|
21
|
+
"list_expenses",
|
|
22
|
+
"get_expense",
|
|
23
|
+
"create_expense",
|
|
24
|
+
"list_clients",
|
|
25
|
+
"get_client",
|
|
26
|
+
"create_client",
|
|
27
|
+
"list_products",
|
|
28
|
+
"get_product",
|
|
29
|
+
"list_quotes",
|
|
30
|
+
"get_quote",
|
|
31
|
+
"create_quote",
|
|
32
|
+
"create_invoice",
|
|
33
|
+
]);
|
|
34
|
+
export const GOOGLE_CANDIDATE_TOOL_COUNT = GOOGLE_CANDIDATE_TOOLS.size; // 18
|
|
35
|
+
export const GOOGLE_INSTRUCTIONS = `Frihet ERP — natural-language business and financial management for Google Connected Apps (Gemini & Search).
|
|
36
|
+
Use get_business_context for complete company health and plan limits.
|
|
37
|
+
Query and review invoices, expenses, quotes, clients, and products with pagination.
|
|
38
|
+
All created invoices are drafts. Confirm parameters with the user before creating records.`;
|
|
39
|
+
export function googleToolResult(result) {
|
|
40
|
+
if (result === null || typeof result !== "object")
|
|
41
|
+
return result;
|
|
42
|
+
const res = result;
|
|
43
|
+
// Deep-redact structured output if present (in-place deletion of sensitive fields)
|
|
44
|
+
if (res.structuredContent && typeof res.structuredContent === "object") {
|
|
45
|
+
deepRedact(res.structuredContent);
|
|
46
|
+
}
|
|
47
|
+
// Redact text content items
|
|
48
|
+
if (Array.isArray(res.content)) {
|
|
49
|
+
res.content = res.content.map((item) => {
|
|
50
|
+
if (item && typeof item === "object" && "text" in item && typeof item.text === "string") {
|
|
51
|
+
return {
|
|
52
|
+
...item,
|
|
53
|
+
text: redactText(item.text),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return item;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return res;
|
|
60
|
+
}
|
|
61
|
+
export const GOOGLE_FORCED_INPUT_VALUES = {
|
|
62
|
+
create_invoice: { status: "draft" },
|
|
63
|
+
create_quote: { status: "draft" },
|
|
64
|
+
};
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
66
|
+
export function applyGoogleProfile(server) {
|
|
67
|
+
const registerTool = server.registerTool.bind(server);
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
|
+
server.registerTool = (name, config, handler) => {
|
|
70
|
+
if (!GOOGLE_CANDIDATE_TOOLS.has(name))
|
|
71
|
+
return undefined;
|
|
72
|
+
let description = config.description ?? "";
|
|
73
|
+
let inputSchema = config.inputSchema;
|
|
74
|
+
if (name === "create_invoice") {
|
|
75
|
+
description = `${description} [Google Connected Apps: Generates an invoice strictly in 'draft' status for human review. No irreversible fiscal submission occurs.]`;
|
|
76
|
+
if (inputSchema && typeof inputSchema === "object" && "status" in inputSchema) {
|
|
77
|
+
const { status: _omittedStatus, ...rest } = inputSchema;
|
|
78
|
+
inputSchema = rest;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (name === "create_quote") {
|
|
82
|
+
description = `${description} [Google Connected Apps: Generates a quote strictly in 'draft' status for human review.]`;
|
|
83
|
+
if (inputSchema && typeof inputSchema === "object" && "status" in inputSchema) {
|
|
84
|
+
const { status: _omittedStatus, ...rest } = inputSchema;
|
|
85
|
+
inputSchema = rest;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return registerTool(name, {
|
|
89
|
+
...config,
|
|
90
|
+
description,
|
|
91
|
+
inputSchema,
|
|
92
|
+
annotations: {
|
|
93
|
+
...config.annotations,
|
|
94
|
+
...(config.annotations?.readOnlyHint !== true ? { destructiveHint: true } : {}),
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
98
|
+
async (...args) => {
|
|
99
|
+
try {
|
|
100
|
+
let input = args[0];
|
|
101
|
+
if (input && typeof input === "object") {
|
|
102
|
+
const forced = GOOGLE_FORCED_INPUT_VALUES[name];
|
|
103
|
+
if (forced) {
|
|
104
|
+
input = { ...input, ...forced };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const res = await handler(input, ...args.slice(1));
|
|
108
|
+
return googleToolResult(res);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return googleToolResult({
|
|
112
|
+
isError: true,
|
|
113
|
+
_meta: { "io.frihet/operationOutcomeUnknown": true },
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
// Google Connected Apps profile intentionally registers 0 raw prompts or dynamic resources
|
|
119
|
+
server.registerResource = () => undefined;
|
|
120
|
+
server.registerPrompt = () => undefined;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=google-profile.js.map
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,9 @@ const PKG_VERSION = (() => {
|
|
|
30
30
|
}
|
|
31
31
|
})();
|
|
32
32
|
import { OPENAI_ALLOWED_TOOL_COUNT, OPENAI_EXCLUDED_COUNT, OPENAI_EXCLUDED_RESOURCE_COUNT } from "./openai-profile.js";
|
|
33
|
+
import { CLAUDE_CANDIDATE_INSTRUCTIONS, CLAUDE_CANDIDATE_TOOLS } from "./claude-profile.js";
|
|
34
|
+
import { GOOGLE_INSTRUCTIONS, GOOGLE_CANDIDATE_TOOL_COUNT } from "./google-profile.js";
|
|
35
|
+
import { MUSE_INSTRUCTIONS, MUSE_CANDIDATE_TOOL_COUNT } from "./muse-profile.js";
|
|
33
36
|
import { resolveToolMode, GROUPED_META_TOOL_COUNT } from "./tool-exposure.js";
|
|
34
37
|
import { localMcpSurfaceComposition, registerMcpSurface, } from "./server-composition.js";
|
|
35
38
|
import { AGENT_SERVER_INSTRUCTIONS, API_KEY_LOCATION, } from "./agent-onboarding.js";
|
|
@@ -37,6 +40,15 @@ import { log } from "./logger.js";
|
|
|
37
40
|
import { registerShutdownHook } from "./metrics.js";
|
|
38
41
|
import { setTraceContext } from "./observability.js";
|
|
39
42
|
function main() {
|
|
43
|
+
const openaiMode = process.env.FRIHET_OPENAI_MODE === "true";
|
|
44
|
+
const claudeMode = process.env.FRIHET_CLAUDE_MODE === "true";
|
|
45
|
+
const googleMode = process.env.FRIHET_GOOGLE_MODE === "true";
|
|
46
|
+
const museMode = process.env.FRIHET_MUSE_MODE === "true";
|
|
47
|
+
const activeModes = [openaiMode, claudeMode, googleMode, museMode].filter(Boolean).length;
|
|
48
|
+
if (activeModes > 1) {
|
|
49
|
+
console.error("Error: FRIHET_OPENAI_MODE, FRIHET_CLAUDE_MODE, FRIHET_GOOGLE_MODE, and FRIHET_MUSE_MODE are mutually exclusive");
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
40
52
|
const apiKey = process.env.FRIHET_API_KEY;
|
|
41
53
|
// Demo mode: FRIHET_DEMO=1|true serves fixture-backed example data with NO
|
|
42
54
|
// network calls and NO API key required. It's an explicit opt-in, so it wins
|
|
@@ -95,17 +107,29 @@ function main() {
|
|
|
95
107
|
const server = new McpServer({
|
|
96
108
|
name: "frihet-erp",
|
|
97
109
|
version: PKG_VERSION,
|
|
98
|
-
description:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
110
|
+
description: claudeMode
|
|
111
|
+
? `Local Claude candidate for Frihet: ${CLAUDE_CANDIDATE_TOOLS.size} canonical operations with reviewed fiscal aliases, 1 currencies resource and 2 receivables prompts. Optional grouped discovery adds 3 names. API-dependent operations require live workspace verification; this is not a published Directory connector.`
|
|
112
|
+
: googleMode
|
|
113
|
+
? `Frihet ERP profile for Google Connected Apps (Gemini & Search): ${GOOGLE_CANDIDATE_TOOL_COUNT} canonical operations with draft-only human-in-the-loop protection.`
|
|
114
|
+
: museMode
|
|
115
|
+
? `Frihet ERP connector for Meta Muse: ${MUSE_CANDIDATE_TOOL_COUNT} canonical operations with draft-only human-in-the-loop protection.`
|
|
116
|
+
:
|
|
117
|
+
"AI-native MCP server for Frihet ERP — invoices, expenses, clients, products, quotes, webhooks, and deposits. " +
|
|
118
|
+
"Provides a catalogue of 158 canonical operations; fiscal aliases and optional grouped discovery names are reported separately. " +
|
|
119
|
+
"The local package serves 11 resources (7 static + 4 API-backed) and 10 workflow prompts " +
|
|
120
|
+
"with full Spanish tax compliance (IVA, IGIC, IPSI).",
|
|
102
121
|
}, {
|
|
103
122
|
// Delivered by `initialize` to every MCP client, which hands it to the model
|
|
104
123
|
// before the first tool call. This is the only onboarding channel that costs
|
|
105
124
|
// the operator zero configuration. Source: src/agent-onboarding.ts.
|
|
106
|
-
instructions:
|
|
125
|
+
instructions: claudeMode
|
|
126
|
+
? CLAUDE_CANDIDATE_INSTRUCTIONS
|
|
127
|
+
: googleMode
|
|
128
|
+
? GOOGLE_INSTRUCTIONS
|
|
129
|
+
: museMode
|
|
130
|
+
? MUSE_INSTRUCTIONS
|
|
131
|
+
: AGENT_SERVER_INSTRUCTIONS,
|
|
107
132
|
});
|
|
108
|
-
const openaiMode = process.env.FRIHET_OPENAI_MODE === "true";
|
|
109
133
|
const toolMode = resolveToolMode();
|
|
110
134
|
if (toolMode === "grouped") {
|
|
111
135
|
log({
|
|
@@ -121,7 +145,7 @@ function main() {
|
|
|
121
145
|
operation: "startup",
|
|
122
146
|
});
|
|
123
147
|
}
|
|
124
|
-
registerMcpSurface(server, client, localMcpSurfaceComposition(openaiMode, toolMode === "grouped"));
|
|
148
|
+
registerMcpSurface(server, client, localMcpSurfaceComposition(openaiMode, toolMode === "grouped", claudeMode, googleMode, museMode));
|
|
125
149
|
// Register shutdown hook to log final metrics summary
|
|
126
150
|
registerShutdownHook();
|
|
127
151
|
// Connect via stdio transport
|
package/dist/logger.d.ts
CHANGED
|
@@ -41,6 +41,6 @@ export declare function logApiCall(method: string, _path: string, statusCode: nu
|
|
|
41
41
|
/**
|
|
42
42
|
* Log a rate-limit retry.
|
|
43
43
|
*/
|
|
44
|
-
export declare function logRetry(method: string, _path: string, retryCount: number, delayMs: number): void;
|
|
44
|
+
export declare function logRetry(method: string, _path: string, retryCount: number, delayMs: number, delaySource?: "retry_after" | "backoff"): void;
|
|
45
45
|
export {};
|
|
46
46
|
//# sourceMappingURL=logger.d.ts.map
|