@agentforge-io/core 2.0.24 → 2.1.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/dist/factory.js +56 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7 -1
- package/dist/services/agent-runner.service.js +18 -4
- package/dist/services/agent.service.d.ts +21 -1
- package/dist/services/agent.service.js +42 -8
- package/dist/services/orchestrator.service.d.ts +40 -1
- package/dist/services/orchestrator.service.js +220 -0
- package/dist/types/agent.types.d.ts +31 -6
- package/package.json +1 -1
- package/dist/adapters/billing/billing-adapter.interface.d.ts +0 -41
- package/dist/adapters/billing/billing-adapter.interface.js +0 -5
- package/dist/adapters/billing/stripe/stripe.adapter.d.ts +0 -30
- package/dist/adapters/billing/stripe/stripe.adapter.js +0 -122
- package/dist/adapters/email/email-adapter.interface.d.ts +0 -25
- package/dist/adapters/email/email-adapter.interface.js +0 -6
- package/dist/adapters/email/noop.adapter.d.ts +0 -10
- package/dist/adapters/email/noop.adapter.js +0 -15
- package/dist/adapters/email/resend.adapter.d.ts +0 -8
- package/dist/adapters/email/resend.adapter.js +0 -39
- package/dist/adapters/upload/noop.adapter.d.ts +0 -9
- package/dist/adapters/upload/noop.adapter.js +0 -14
- package/dist/adapters/upload/s3.adapter.d.ts +0 -38
- package/dist/adapters/upload/s3.adapter.js +0 -69
- package/dist/adapters/upload/upload-adapter.interface.d.ts +0 -37
- package/dist/adapters/upload/upload-adapter.interface.js +0 -15
- package/dist/billing/index.d.ts +0 -12
- package/dist/billing/index.js +0 -28
- package/dist/domain/agent.d.ts +0 -59
- package/dist/domain/agent.js +0 -2
- package/dist/domain/api-key.d.ts +0 -28
- package/dist/domain/api-key.js +0 -2
- package/dist/domain/auth-identity.d.ts +0 -10
- package/dist/domain/auth-identity.js +0 -2
- package/dist/domain/email-token.d.ts +0 -11
- package/dist/domain/email-token.js +0 -2
- package/dist/domain/external-user.d.ts +0 -23
- package/dist/domain/external-user.js +0 -2
- package/dist/domain/plan.d.ts +0 -20
- package/dist/domain/plan.js +0 -2
- package/dist/domain/platform-secret.d.ts +0 -24
- package/dist/domain/platform-secret.js +0 -8
- package/dist/domain/refresh-token.d.ts +0 -15
- package/dist/domain/refresh-token.js +0 -2
- package/dist/domain/subscription.d.ts +0 -21
- package/dist/domain/subscription.js +0 -2
- package/dist/domain/tenant.d.ts +0 -21
- package/dist/domain/tenant.js +0 -2
- package/dist/domain/usage-record.d.ts +0 -15
- package/dist/domain/usage-record.js +0 -2
- package/dist/domain/user.d.ts +0 -43
- package/dist/domain/user.js +0 -2
- package/dist/services/agent-config.service.d.ts +0 -45
- package/dist/services/agent-config.service.js +0 -114
- package/dist/services/api-key.service.d.ts +0 -41
- package/dist/services/api-key.service.js +0 -80
- package/dist/services/auth.service.d.ts +0 -133
- package/dist/services/auth.service.js +0 -411
- package/dist/services/billing.service.d.ts +0 -67
- package/dist/services/billing.service.js +0 -254
- package/dist/services/email-templates.d.ts +0 -18
- package/dist/services/email-templates.js +0 -39
- package/dist/services/email.service.d.ts +0 -26
- package/dist/services/email.service.js +0 -42
- package/dist/services/errors.d.ts +0 -7
- package/dist/services/errors.js +0 -27
- package/dist/services/oauth.service.d.ts +0 -73
- package/dist/services/oauth.service.js +0 -174
- package/dist/services/plan.service.d.ts +0 -54
- package/dist/services/plan.service.js +0 -120
- package/dist/services/refresh-token.service.d.ts +0 -38
- package/dist/services/refresh-token.service.js +0 -73
- package/dist/services/secrets/crypto.d.ts +0 -37
- package/dist/services/secrets/crypto.js +0 -110
- package/dist/services/secrets/known-keys.d.ts +0 -38
- package/dist/services/secrets/known-keys.js +0 -50
- package/dist/services/secrets.service.d.ts +0 -91
- package/dist/services/secrets.service.js +0 -193
- package/dist/services/tenant-billing.service.d.ts +0 -121
- package/dist/services/tenant-billing.service.js +0 -290
- package/dist/services/tenant.service.d.ts +0 -54
- package/dist/services/tenant.service.js +0 -96
- package/dist/services/upload.service.d.ts +0 -37
- package/dist/services/upload.service.js +0 -84
- package/dist/services/usage.service.d.ts +0 -34
- package/dist/services/usage.service.js +0 -108
- package/dist/types/billing.types.d.ts +0 -82
- package/dist/types/billing.types.js +0 -3
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import type { CheckoutSession, CreateCheckoutParams, CreateCustomerParams, CreateSubscriptionParams, SubscriptionResult, WebhookEvent } from '../../types';
|
|
2
|
-
/**
|
|
3
|
-
* IBillingAdapter defines the contract for payment providers.
|
|
4
|
-
* Implement this interface to support any payment gateway (Stripe, Paddle, LemonSqueezy, etc.)
|
|
5
|
-
*/
|
|
6
|
-
export interface IBillingAdapter {
|
|
7
|
-
/**
|
|
8
|
-
* Create a Stripe Checkout (or equivalent) session for a subscription or one-time payment.
|
|
9
|
-
*/
|
|
10
|
-
createCheckoutSession(params: CreateCheckoutParams): Promise<CheckoutSession>;
|
|
11
|
-
/**
|
|
12
|
-
* Programmatically create a subscription (without hosted checkout).
|
|
13
|
-
*/
|
|
14
|
-
createSubscription(params: CreateSubscriptionParams): Promise<SubscriptionResult>;
|
|
15
|
-
/**
|
|
16
|
-
* Cancel a subscription (optionally at period end).
|
|
17
|
-
*/
|
|
18
|
-
cancelSubscription(subscriptionId: string, atPeriodEnd?: boolean): Promise<void>;
|
|
19
|
-
/**
|
|
20
|
-
* Handle an incoming webhook from the payment provider.
|
|
21
|
-
* Returns a normalized WebhookEvent.
|
|
22
|
-
*/
|
|
23
|
-
handleWebhook(payload: Buffer, signature: string): Promise<WebhookEvent>;
|
|
24
|
-
/**
|
|
25
|
-
* Generate a customer portal URL where users can manage their subscription.
|
|
26
|
-
*/
|
|
27
|
-
getPortalUrl(customerId: string, returnUrl: string): Promise<string>;
|
|
28
|
-
/**
|
|
29
|
-
* Create a customer record in the payment provider.
|
|
30
|
-
* Returns the provider-specific customer ID.
|
|
31
|
-
*/
|
|
32
|
-
createCustomer(params: CreateCustomerParams): Promise<string>;
|
|
33
|
-
/**
|
|
34
|
-
* Get the current subscription status from the provider.
|
|
35
|
-
*/
|
|
36
|
-
getSubscription(subscriptionId: string): Promise<SubscriptionResult & {
|
|
37
|
-
status: string;
|
|
38
|
-
}>;
|
|
39
|
-
}
|
|
40
|
-
/** Token to inject the billing adapter via NestJS DI */
|
|
41
|
-
export declare const BILLING_ADAPTER = "BILLING_ADAPTER";
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import Stripe from 'stripe';
|
|
2
|
-
import type { IBillingAdapter } from '../billing-adapter.interface';
|
|
3
|
-
import type { CheckoutSession, CreateCheckoutParams, CreateCustomerParams, CreateSubscriptionParams, PlanDefinition, StripeConfig, SubscriptionResult, WebhookEvent } from '../../../types';
|
|
4
|
-
interface MiniLogger {
|
|
5
|
-
debug?: (m: string) => void;
|
|
6
|
-
warn?: (m: string) => void;
|
|
7
|
-
log?: (m: string) => void;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* StripeAdapter implements IBillingAdapter using the Stripe API.
|
|
11
|
-
* Handles subscriptions, pay-per-use checkouts, webhooks, and customer portal.
|
|
12
|
-
*/
|
|
13
|
-
export declare class StripeAdapter implements IBillingAdapter {
|
|
14
|
-
private readonly logger;
|
|
15
|
-
private readonly stripe;
|
|
16
|
-
private readonly plans;
|
|
17
|
-
private readonly webhookSecret;
|
|
18
|
-
constructor(config: StripeConfig, plans?: PlanDefinition[], logger?: MiniLogger);
|
|
19
|
-
createCustomer(params: CreateCustomerParams): Promise<string>;
|
|
20
|
-
createCheckoutSession(params: CreateCheckoutParams): Promise<CheckoutSession>;
|
|
21
|
-
createSubscription(params: CreateSubscriptionParams): Promise<SubscriptionResult>;
|
|
22
|
-
cancelSubscription(subscriptionId: string, atPeriodEnd?: boolean): Promise<void>;
|
|
23
|
-
getSubscription(subscriptionId: string): Promise<SubscriptionResult & {
|
|
24
|
-
status: string;
|
|
25
|
-
}>;
|
|
26
|
-
getPortalUrl(customerId: string, returnUrl: string): Promise<string>;
|
|
27
|
-
handleWebhook(payload: Buffer, signature: string): Promise<WebhookEvent>;
|
|
28
|
-
getStripeInstance(): Stripe;
|
|
29
|
-
}
|
|
30
|
-
export {};
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.StripeAdapter = void 0;
|
|
7
|
-
const stripe_1 = __importDefault(require("stripe"));
|
|
8
|
-
/**
|
|
9
|
-
* StripeAdapter implements IBillingAdapter using the Stripe API.
|
|
10
|
-
* Handles subscriptions, pay-per-use checkouts, webhooks, and customer portal.
|
|
11
|
-
*/
|
|
12
|
-
class StripeAdapter {
|
|
13
|
-
constructor(config, plans = [], logger) {
|
|
14
|
-
this.logger = logger ?? {};
|
|
15
|
-
this.stripe = new stripe_1.default(config.secretKey, {
|
|
16
|
-
apiVersion: '2023-10-16',
|
|
17
|
-
});
|
|
18
|
-
this.plans = plans;
|
|
19
|
-
this.webhookSecret = config.webhookSecret;
|
|
20
|
-
}
|
|
21
|
-
// ─── Customer ─────────────────────────────────────────────────────────────
|
|
22
|
-
async createCustomer(params) {
|
|
23
|
-
const customer = await this.stripe.customers.create({
|
|
24
|
-
email: params.email,
|
|
25
|
-
name: params.name,
|
|
26
|
-
metadata: params.metadata ?? {},
|
|
27
|
-
});
|
|
28
|
-
this.logger.debug?.(`Created Stripe customer: ${customer.id}`);
|
|
29
|
-
return customer.id;
|
|
30
|
-
}
|
|
31
|
-
// ─── Checkout ─────────────────────────────────────────────────────────────
|
|
32
|
-
async createCheckoutSession(params) {
|
|
33
|
-
// Prefer the caller-provided stripePriceId (DB-backed plans flow).
|
|
34
|
-
// Fall back to looking it up in the static plan list passed to the
|
|
35
|
-
// constructor (legacy / single-tenant flow).
|
|
36
|
-
const fallbackPlan = this.plans.find((p) => p.id === params.planId);
|
|
37
|
-
const stripePriceId = params.stripePriceId ?? fallbackPlan?.stripePriceId;
|
|
38
|
-
const interval = fallbackPlan?.interval ?? 'month';
|
|
39
|
-
if (!stripePriceId) {
|
|
40
|
-
throw new Error(`Plan "${params.planId}" has no Stripe price ID configured`);
|
|
41
|
-
}
|
|
42
|
-
const session = await this.stripe.checkout.sessions.create({
|
|
43
|
-
mode: interval ? 'subscription' : 'payment',
|
|
44
|
-
payment_method_types: ['card'],
|
|
45
|
-
line_items: [{ price: stripePriceId, quantity: 1 }],
|
|
46
|
-
success_url: params.successUrl,
|
|
47
|
-
cancel_url: params.cancelUrl,
|
|
48
|
-
metadata: {
|
|
49
|
-
userId: params.userId,
|
|
50
|
-
planId: params.planId,
|
|
51
|
-
...params.metadata,
|
|
52
|
-
},
|
|
53
|
-
subscription_data: interval
|
|
54
|
-
? { metadata: { userId: params.userId, planId: params.planId } }
|
|
55
|
-
: undefined,
|
|
56
|
-
});
|
|
57
|
-
return { sessionId: session.id, url: session.url };
|
|
58
|
-
}
|
|
59
|
-
// ─── Subscription ─────────────────────────────────────────────────────────
|
|
60
|
-
async createSubscription(params) {
|
|
61
|
-
const subscription = await this.stripe.subscriptions.create({
|
|
62
|
-
customer: params.customerId,
|
|
63
|
-
items: [{ price: params.priceId }],
|
|
64
|
-
trial_period_days: params.trialDays,
|
|
65
|
-
payment_behavior: 'default_incomplete',
|
|
66
|
-
expand: ['latest_invoice.payment_intent'],
|
|
67
|
-
});
|
|
68
|
-
return {
|
|
69
|
-
subscriptionId: subscription.id,
|
|
70
|
-
status: subscription.status,
|
|
71
|
-
currentPeriodEnd: new Date(subscription.current_period_end * 1000),
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
async cancelSubscription(subscriptionId, atPeriodEnd = true) {
|
|
75
|
-
if (atPeriodEnd) {
|
|
76
|
-
await this.stripe.subscriptions.update(subscriptionId, {
|
|
77
|
-
cancel_at_period_end: true,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
await this.stripe.subscriptions.cancel(subscriptionId);
|
|
82
|
-
}
|
|
83
|
-
this.logger.log?.(`Subscription ${subscriptionId} cancelled (atPeriodEnd=${atPeriodEnd})`);
|
|
84
|
-
}
|
|
85
|
-
async getSubscription(subscriptionId) {
|
|
86
|
-
const sub = await this.stripe.subscriptions.retrieve(subscriptionId);
|
|
87
|
-
return {
|
|
88
|
-
subscriptionId: sub.id,
|
|
89
|
-
status: sub.status,
|
|
90
|
-
currentPeriodEnd: new Date(sub.current_period_end * 1000),
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
// ─── Customer Portal ──────────────────────────────────────────────────────
|
|
94
|
-
async getPortalUrl(customerId, returnUrl) {
|
|
95
|
-
const session = await this.stripe.billingPortal.sessions.create({
|
|
96
|
-
customer: customerId,
|
|
97
|
-
return_url: returnUrl,
|
|
98
|
-
});
|
|
99
|
-
return session.url;
|
|
100
|
-
}
|
|
101
|
-
// ─── Webhooks ─────────────────────────────────────────────────────────────
|
|
102
|
-
async handleWebhook(payload, signature) {
|
|
103
|
-
let event;
|
|
104
|
-
try {
|
|
105
|
-
event = this.stripe.webhooks.constructEvent(payload, signature, this.webhookSecret);
|
|
106
|
-
}
|
|
107
|
-
catch (err) {
|
|
108
|
-
throw new Error(`Stripe webhook verification failed: ${err}`);
|
|
109
|
-
}
|
|
110
|
-
this.logger.debug?.(`Stripe webhook received: ${event.type}`);
|
|
111
|
-
// Normalize to a generic WebhookEvent
|
|
112
|
-
return {
|
|
113
|
-
type: event.type,
|
|
114
|
-
data: event.data.object,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
// ─── Helpers ──────────────────────────────────────────────────────────────
|
|
118
|
-
getStripeInstance() {
|
|
119
|
-
return this.stripe;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
exports.StripeAdapter = StripeAdapter;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transport-agnostic contract for sending email.
|
|
3
|
-
*
|
|
4
|
-
* Default implementation is Resend. Plug in SES/SendGrid/SMTP/Mailgun/etc.
|
|
5
|
-
* via `auth.email.provider = 'custom'` + `customAdapter` in config, or by
|
|
6
|
-
* overriding the EMAIL_ADAPTER provider in the consuming app's module.
|
|
7
|
-
*/
|
|
8
|
-
export interface EmailAdapter {
|
|
9
|
-
send(message: EmailMessage): Promise<EmailSendResult>;
|
|
10
|
-
}
|
|
11
|
-
export interface EmailMessage {
|
|
12
|
-
to: string;
|
|
13
|
-
subject: string;
|
|
14
|
-
html?: string;
|
|
15
|
-
text?: string;
|
|
16
|
-
/** Override the default `from` for this single send. */
|
|
17
|
-
from?: string;
|
|
18
|
-
/** Tags / metadata for analytics — adapter may ignore. */
|
|
19
|
-
tags?: Record<string, string>;
|
|
20
|
-
}
|
|
21
|
-
export interface EmailSendResult {
|
|
22
|
-
/** Provider's message id, when available. */
|
|
23
|
-
id?: string;
|
|
24
|
-
}
|
|
25
|
-
export declare const EMAIL_ADAPTER = "AGENTFORGE_EMAIL_ADAPTER";
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EMAIL_ADAPTER = void 0;
|
|
4
|
-
// String token (not Symbol) so it survives duplicate package instances and
|
|
5
|
-
// works as a NestJS string-based DI provider out of the box.
|
|
6
|
-
exports.EMAIL_ADAPTER = 'AGENTFORGE_EMAIL_ADAPTER';
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { EmailAdapter, EmailMessage, EmailSendResult } from './email-adapter.interface';
|
|
2
|
-
/**
|
|
3
|
-
* Used when no email config is provided. Throws on send so callers (verify,
|
|
4
|
-
* password-reset) fail loudly instead of silently dropping. AuthService wraps
|
|
5
|
-
* the call in try/catch where appropriate (e.g. password-reset to preserve
|
|
6
|
-
* the always-200 anti-enumeration guarantee).
|
|
7
|
-
*/
|
|
8
|
-
export declare class NoopEmailAdapter implements EmailAdapter {
|
|
9
|
-
send(_message: EmailMessage): Promise<EmailSendResult>;
|
|
10
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NoopEmailAdapter = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Used when no email config is provided. Throws on send so callers (verify,
|
|
6
|
-
* password-reset) fail loudly instead of silently dropping. AuthService wraps
|
|
7
|
-
* the call in try/catch where appropriate (e.g. password-reset to preserve
|
|
8
|
-
* the always-200 anti-enumeration guarantee).
|
|
9
|
-
*/
|
|
10
|
-
class NoopEmailAdapter {
|
|
11
|
-
async send(_message) {
|
|
12
|
-
throw new Error('Email features are not configured. Pass an EmailAdapter (e.g. ResendAdapter) when creating AgentForge.');
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
exports.NoopEmailAdapter = NoopEmailAdapter;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { EmailAdapter, EmailMessage, EmailSendResult } from './email-adapter.interface';
|
|
2
|
-
export declare class ResendAdapter implements EmailAdapter {
|
|
3
|
-
private readonly apiKey;
|
|
4
|
-
private readonly defaultFrom;
|
|
5
|
-
private readonly client;
|
|
6
|
-
constructor(apiKey: string, defaultFrom: string);
|
|
7
|
-
send(message: EmailMessage): Promise<EmailSendResult>;
|
|
8
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ResendAdapter = void 0;
|
|
4
|
-
const resend_1 = require("resend");
|
|
5
|
-
class ResendAdapter {
|
|
6
|
-
constructor(apiKey, defaultFrom) {
|
|
7
|
-
this.apiKey = apiKey;
|
|
8
|
-
this.defaultFrom = defaultFrom;
|
|
9
|
-
if (!apiKey)
|
|
10
|
-
throw new Error('ResendAdapter: apiKey is required');
|
|
11
|
-
if (!defaultFrom) {
|
|
12
|
-
throw new Error('ResendAdapter: defaultFrom is required (e.g. "App <noreply@yourdomain.com>")');
|
|
13
|
-
}
|
|
14
|
-
this.client = new resend_1.Resend(apiKey);
|
|
15
|
-
}
|
|
16
|
-
async send(message) {
|
|
17
|
-
const payload = {
|
|
18
|
-
from: message.from ?? this.defaultFrom,
|
|
19
|
-
to: [message.to],
|
|
20
|
-
subject: message.subject,
|
|
21
|
-
};
|
|
22
|
-
if (message.html)
|
|
23
|
-
payload.html = message.html;
|
|
24
|
-
if (message.text)
|
|
25
|
-
payload.text = message.text;
|
|
26
|
-
if (message.tags) {
|
|
27
|
-
payload.tags = Object.entries(message.tags).map(([name, value]) => ({ name, value }));
|
|
28
|
-
}
|
|
29
|
-
if (!payload.html && !payload.text) {
|
|
30
|
-
throw new Error('ResendAdapter: html or text is required');
|
|
31
|
-
}
|
|
32
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
-
const { data, error } = await this.client.emails.send(payload);
|
|
34
|
-
if (error)
|
|
35
|
-
throw new Error(`Resend: ${error.message}`);
|
|
36
|
-
return { id: data?.id };
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
exports.ResendAdapter = ResendAdapter;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { UploadAdapter } from './upload-adapter.interface';
|
|
2
|
-
/**
|
|
3
|
-
* Used when no upload adapter is wired. Any sign request throws so the
|
|
4
|
-
* controller returns a clear 501 to the client instead of pretending to
|
|
5
|
-
* generate a URL that nobody can PUT to.
|
|
6
|
-
*/
|
|
7
|
-
export declare class NoopUploadAdapter implements UploadAdapter {
|
|
8
|
-
signUpload(): Promise<never>;
|
|
9
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NoopUploadAdapter = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Used when no upload adapter is wired. Any sign request throws so the
|
|
6
|
-
* controller returns a clear 501 to the client instead of pretending to
|
|
7
|
-
* generate a URL that nobody can PUT to.
|
|
8
|
-
*/
|
|
9
|
-
class NoopUploadAdapter {
|
|
10
|
-
async signUpload() {
|
|
11
|
-
throw new Error('Uploads are not configured. Pass an UploadAdapter (e.g. S3UploadAdapter) when creating AgentForge.');
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
exports.NoopUploadAdapter = NoopUploadAdapter;
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { SignUploadInput, SignedUploadTarget, UploadAdapter } from './upload-adapter.interface';
|
|
2
|
-
export interface S3UploadAdapterOptions {
|
|
3
|
-
region: string;
|
|
4
|
-
bucket: string;
|
|
5
|
-
/** AWS access key id. Omit when running on an EC2/EKS instance with an IAM
|
|
6
|
-
* role — the SDK's default credential chain picks it up. */
|
|
7
|
-
accessKeyId?: string;
|
|
8
|
-
secretAccessKey?: string;
|
|
9
|
-
/**
|
|
10
|
-
* Public URL prefix the object will be reachable at. Required because we
|
|
11
|
-
* don't assume CloudFront vs raw S3 vs custom domain. The adapter
|
|
12
|
-
* concatenates `${publicUrlBase}/${key}` for `publicUrl`.
|
|
13
|
-
* Examples:
|
|
14
|
-
* "https://my-bucket.s3.us-east-1.amazonaws.com"
|
|
15
|
-
* "https://cdn.example.com"
|
|
16
|
-
*/
|
|
17
|
-
publicUrlBase: string;
|
|
18
|
-
/** PUT URL TTL in seconds. Short by default so the upload window can't be
|
|
19
|
-
* reused by a leaked URL hours later. */
|
|
20
|
-
signedUrlTtlSeconds?: number;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* S3 (or S3-compatible — R2, Spaces, MinIO) signed-upload adapter. Uses the
|
|
24
|
-
* official AWS SDK v3 so it talks to any provider that implements the S3 API.
|
|
25
|
-
*
|
|
26
|
-
* Read access model: the adapter assumes objects are world-readable once
|
|
27
|
-
* uploaded (`publicUrlBase` is GETtable). If your bucket is private and you
|
|
28
|
-
* need signed GETs at read-time too, fork this adapter — the interface is
|
|
29
|
-
* intentionally minimal.
|
|
30
|
-
*/
|
|
31
|
-
export declare class S3UploadAdapter implements UploadAdapter {
|
|
32
|
-
private readonly client;
|
|
33
|
-
private readonly bucket;
|
|
34
|
-
private readonly publicUrlBase;
|
|
35
|
-
private readonly ttl;
|
|
36
|
-
constructor(opts: S3UploadAdapterOptions);
|
|
37
|
-
signUpload(input: SignUploadInput): Promise<SignedUploadTarget>;
|
|
38
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.S3UploadAdapter = void 0;
|
|
4
|
-
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
5
|
-
const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner");
|
|
6
|
-
/**
|
|
7
|
-
* S3 (or S3-compatible — R2, Spaces, MinIO) signed-upload adapter. Uses the
|
|
8
|
-
* official AWS SDK v3 so it talks to any provider that implements the S3 API.
|
|
9
|
-
*
|
|
10
|
-
* Read access model: the adapter assumes objects are world-readable once
|
|
11
|
-
* uploaded (`publicUrlBase` is GETtable). If your bucket is private and you
|
|
12
|
-
* need signed GETs at read-time too, fork this adapter — the interface is
|
|
13
|
-
* intentionally minimal.
|
|
14
|
-
*/
|
|
15
|
-
class S3UploadAdapter {
|
|
16
|
-
constructor(opts) {
|
|
17
|
-
if (!opts.bucket)
|
|
18
|
-
throw new Error('S3UploadAdapter: bucket is required');
|
|
19
|
-
if (!opts.region)
|
|
20
|
-
throw new Error('S3UploadAdapter: region is required');
|
|
21
|
-
if (!opts.publicUrlBase) {
|
|
22
|
-
throw new Error('S3UploadAdapter: publicUrlBase is required');
|
|
23
|
-
}
|
|
24
|
-
this.bucket = opts.bucket;
|
|
25
|
-
this.publicUrlBase = opts.publicUrlBase.replace(/\/+$/, '');
|
|
26
|
-
this.ttl = opts.signedUrlTtlSeconds ?? 300;
|
|
27
|
-
this.client = new client_s3_1.S3Client({
|
|
28
|
-
region: opts.region,
|
|
29
|
-
// Only override credentials when explicit keys were passed. Otherwise
|
|
30
|
-
// let the SDK fall through to its standard provider chain (env vars,
|
|
31
|
-
// shared credentials file, IAM role, etc.) — that's what production
|
|
32
|
-
// deployments on AWS expect.
|
|
33
|
-
...(opts.accessKeyId && opts.secretAccessKey
|
|
34
|
-
? {
|
|
35
|
-
credentials: {
|
|
36
|
-
accessKeyId: opts.accessKeyId,
|
|
37
|
-
secretAccessKey: opts.secretAccessKey,
|
|
38
|
-
},
|
|
39
|
-
}
|
|
40
|
-
: {}),
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
async signUpload(input) {
|
|
44
|
-
if (!input.key)
|
|
45
|
-
throw new Error('signUpload: key is required');
|
|
46
|
-
if (!input.contentType)
|
|
47
|
-
throw new Error('signUpload: contentType is required');
|
|
48
|
-
const cmd = new client_s3_1.PutObjectCommand({
|
|
49
|
-
Bucket: this.bucket,
|
|
50
|
-
Key: input.key,
|
|
51
|
-
ContentType: input.contentType,
|
|
52
|
-
// ContentLength can't be locked into a presigned URL on plain S3 — the
|
|
53
|
-
// SDK only includes signed headers, and the client controls the
|
|
54
|
-
// Content-Length header. Enforce size at the app layer (callers
|
|
55
|
-
// check the response Content-Length on a HEAD after upload, or trust
|
|
56
|
-
// the size they already validated client-side).
|
|
57
|
-
});
|
|
58
|
-
const uploadUrl = await (0, s3_request_presigner_1.getSignedUrl)(this.client, cmd, {
|
|
59
|
-
expiresIn: this.ttl,
|
|
60
|
-
});
|
|
61
|
-
return {
|
|
62
|
-
uploadUrl,
|
|
63
|
-
publicUrl: `${this.publicUrlBase}/${input.key}`,
|
|
64
|
-
key: input.key,
|
|
65
|
-
expiresInSeconds: this.ttl,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
exports.S3UploadAdapter = S3UploadAdapter;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provider-agnostic contract for object storage. The default adapter signs
|
|
3
|
-
* S3 PUTs; consumers running on R2, Backblaze B2, or Supabase Storage can
|
|
4
|
-
* write their own and pass it to `createAgentForge({ adapters: { upload } })`.
|
|
5
|
-
*
|
|
6
|
-
* Direct-upload flow (signed PUT) instead of streaming through our backend:
|
|
7
|
-
* 1. Client asks us for a signed URL.
|
|
8
|
-
* 2. We validate intent (MIME, size, scope), generate a key, sign the PUT.
|
|
9
|
-
* 3. Client uploads the bytes straight to the storage provider.
|
|
10
|
-
* 4. The persisted `publicUrl` is what other clients read later.
|
|
11
|
-
*/
|
|
12
|
-
export interface SignedUploadTarget {
|
|
13
|
-
/** Pre-authorized URL the client PUTs the file body to. Short-lived. */
|
|
14
|
-
uploadUrl: string;
|
|
15
|
-
/** The eventual GETtable URL once the upload finishes. */
|
|
16
|
-
publicUrl: string;
|
|
17
|
-
/** Object key inside the bucket — useful when callers want to associate
|
|
18
|
-
* the upload with a domain entity for later cleanup. */
|
|
19
|
-
key: string;
|
|
20
|
-
/** Seconds until `uploadUrl` stops being honored by the provider. */
|
|
21
|
-
expiresInSeconds: number;
|
|
22
|
-
}
|
|
23
|
-
export interface SignUploadInput {
|
|
24
|
-
/** Object key path. Adapter is free to add randomness for collision safety. */
|
|
25
|
-
key: string;
|
|
26
|
-
/** Content-Type the client will declare on PUT. Adapters MUST require the
|
|
27
|
-
* same value at PUT time so a different MIME can't be smuggled in. */
|
|
28
|
-
contentType: string;
|
|
29
|
-
/** Max content-length the signed URL will accept. Soft hint to the adapter
|
|
30
|
-
* — providers that don't support content-length pre-sign should still
|
|
31
|
-
* return the URL and rely on app-level validation. */
|
|
32
|
-
maxSizeBytes?: number;
|
|
33
|
-
}
|
|
34
|
-
export interface UploadAdapter {
|
|
35
|
-
signUpload(input: SignUploadInput): Promise<SignedUploadTarget>;
|
|
36
|
-
}
|
|
37
|
-
export declare const UPLOAD_ADAPTER = "AGENTFORGE_UPLOAD_ADAPTER";
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Provider-agnostic contract for object storage. The default adapter signs
|
|
4
|
-
* S3 PUTs; consumers running on R2, Backblaze B2, or Supabase Storage can
|
|
5
|
-
* write their own and pass it to `createAgentForge({ adapters: { upload } })`.
|
|
6
|
-
*
|
|
7
|
-
* Direct-upload flow (signed PUT) instead of streaming through our backend:
|
|
8
|
-
* 1. Client asks us for a signed URL.
|
|
9
|
-
* 2. We validate intent (MIME, size, scope), generate a key, sign the PUT.
|
|
10
|
-
* 3. Client uploads the bytes straight to the storage provider.
|
|
11
|
-
* 4. The persisted `publicUrl` is what other clients read later.
|
|
12
|
-
*/
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.UPLOAD_ADAPTER = void 0;
|
|
15
|
-
exports.UPLOAD_ADAPTER = 'AGENTFORGE_UPLOAD_ADAPTER';
|
package/dist/billing/index.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export type { Plan, NewPlan, PlanPatch, UsageLimits, } from '../domain/plan';
|
|
2
|
-
export type { Subscription, NewSubscription, SubscriptionPatch, } from '../domain/subscription';
|
|
3
|
-
export type { SubscriptionStatus, PaymentStatus, UserSubscription, UsageSummary, UsageRecord, CheckoutResult, PortalResult, BillingOverviewResult, InvoiceRecord, } from '../types/billing.types';
|
|
4
|
-
export type { BillingProvider, BillingModel, BillingConfig, StripeConfig, PlanDefinition, CreditsConfig, } from '../types/config.types';
|
|
5
|
-
export type { PlanRepository, SubscriptionRepository, UsageRecordRepository, } from '../repositories';
|
|
6
|
-
export type { IBillingAdapter } from '../adapters/billing/billing-adapter.interface';
|
|
7
|
-
export { BILLING_ADAPTER } from '../adapters/billing/billing-adapter.interface';
|
|
8
|
-
export { StripeAdapter } from '../adapters/billing/stripe/stripe.adapter';
|
|
9
|
-
export { UsageService, type UsageServiceOptions } from '../services/usage.service';
|
|
10
|
-
export { PlanService } from '../services/plan.service';
|
|
11
|
-
export { BillingService } from '../services/billing.service';
|
|
12
|
-
export { TenantBillingService } from '../services/tenant-billing.service';
|
package/dist/billing/index.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// ─── @agentforge/core/billing — narrow surface for commercial code ─────────
|
|
3
|
-
//
|
|
4
|
-
// This sub-path exposes ONLY the billing/commercial slice of the core
|
|
5
|
-
// library. Consumers that don't want to pull in the full AI surface (and
|
|
6
|
-
// don't want their type-checker to suggest AI internals on autocomplete)
|
|
7
|
-
// can import from here.
|
|
8
|
-
//
|
|
9
|
-
// Architecturally the files still live alongside the AI code in
|
|
10
|
-
// `packages/core/src/`; this is a narrowed re-export, not a physical move.
|
|
11
|
-
// The goal is to make the seam visible and lintable today, and to make a
|
|
12
|
-
// later physical extraction (to `apps/server/modules/billing/`, or to a
|
|
13
|
-
// separate `@agentforge/billing` package) a localized change.
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.TenantBillingService = exports.BillingService = exports.PlanService = exports.UsageService = exports.StripeAdapter = exports.BILLING_ADAPTER = void 0;
|
|
16
|
-
var billing_adapter_interface_1 = require("../adapters/billing/billing-adapter.interface");
|
|
17
|
-
Object.defineProperty(exports, "BILLING_ADAPTER", { enumerable: true, get: function () { return billing_adapter_interface_1.BILLING_ADAPTER; } });
|
|
18
|
-
var stripe_adapter_1 = require("../adapters/billing/stripe/stripe.adapter");
|
|
19
|
-
Object.defineProperty(exports, "StripeAdapter", { enumerable: true, get: function () { return stripe_adapter_1.StripeAdapter; } });
|
|
20
|
-
// ─── Services ──────────────────────────────────────────────────────────────
|
|
21
|
-
var usage_service_1 = require("../services/usage.service");
|
|
22
|
-
Object.defineProperty(exports, "UsageService", { enumerable: true, get: function () { return usage_service_1.UsageService; } });
|
|
23
|
-
var plan_service_1 = require("../services/plan.service");
|
|
24
|
-
Object.defineProperty(exports, "PlanService", { enumerable: true, get: function () { return plan_service_1.PlanService; } });
|
|
25
|
-
var billing_service_1 = require("../services/billing.service");
|
|
26
|
-
Object.defineProperty(exports, "BillingService", { enumerable: true, get: function () { return billing_service_1.BillingService; } });
|
|
27
|
-
var tenant_billing_service_1 = require("../services/tenant-billing.service");
|
|
28
|
-
Object.defineProperty(exports, "TenantBillingService", { enumerable: true, get: function () { return tenant_billing_service_1.TenantBillingService; } });
|
package/dist/domain/agent.d.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { McpServerConfig } from '../types/config.types';
|
|
2
|
-
/**
|
|
3
|
-
* Visual customization shared by every embed of an agent — the public widget
|
|
4
|
-
* (`/widget.js`) and the iframe view both read this. Lives on the agent so a
|
|
5
|
-
* single edit ripples through every site that's embedded it; per-token
|
|
6
|
-
* theming is intentionally NOT supported (was a misfeature). All fields
|
|
7
|
-
* optional — widget falls back to its built-in defaults for anything omitted.
|
|
8
|
-
*/
|
|
9
|
-
export interface AgentAppearance {
|
|
10
|
-
primaryColor?: string;
|
|
11
|
-
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
|
|
12
|
-
title?: string;
|
|
13
|
-
greeting?: string;
|
|
14
|
-
avatarUrl?: string;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Persisted agent configuration scoped to a Tenant. Created and edited from
|
|
18
|
-
* the admin UI; resolved by the SDK at runtime via `(tenantId, slug)`.
|
|
19
|
-
*
|
|
20
|
-
* Shape is intentionally a superset of `AgentDefinition` (the in-process
|
|
21
|
-
* config object used today) plus DB metadata. The orchestrator/runner only
|
|
22
|
-
* needs the prompt/model/limits/tools — everything else here is for
|
|
23
|
-
* lifecycle: who created it, when, is it still active.
|
|
24
|
-
*/
|
|
25
|
-
export interface AgentRecord {
|
|
26
|
-
id: string;
|
|
27
|
-
/** Owner tenant — every lookup is scoped to this. */
|
|
28
|
-
tenantId: string;
|
|
29
|
-
/** Human-friendly identifier the SDK uses, e.g. `support-bot`.
|
|
30
|
-
* Unique within a tenant, not globally. */
|
|
31
|
-
slug: string;
|
|
32
|
-
name: string;
|
|
33
|
-
description?: string;
|
|
34
|
-
/** Claude model id, e.g. `claude-sonnet-4-6`. */
|
|
35
|
-
model?: string;
|
|
36
|
-
systemPrompt: string;
|
|
37
|
-
/** Optional plain-text knowledge prepended to the system prompt at run-time.
|
|
38
|
-
* No retrieval — this is the cheap path before RAG. */
|
|
39
|
-
context?: string;
|
|
40
|
-
temperature?: number;
|
|
41
|
-
topP?: number;
|
|
42
|
-
maxTokens?: number;
|
|
43
|
-
/** Tool ids the agent can use. Persisted but not yet exposed in the UI. */
|
|
44
|
-
tools?: string[];
|
|
45
|
-
/** MCP servers the agent can connect to. Same caveat as `tools`. */
|
|
46
|
-
mcpServers?: McpServerConfig[];
|
|
47
|
-
/** Visual customization for embeds. Single source of truth — applies to
|
|
48
|
-
* every chat token issued for this agent. */
|
|
49
|
-
appearance?: AgentAppearance;
|
|
50
|
-
/** Soft-delete: keeps history intact while hiding from active use. */
|
|
51
|
-
isActive: boolean;
|
|
52
|
-
/** UserId of the platform user who created the agent (audit trail). */
|
|
53
|
-
createdByUserId?: string;
|
|
54
|
-
metadata?: Record<string, unknown>;
|
|
55
|
-
createdAt: Date;
|
|
56
|
-
updatedAt: Date;
|
|
57
|
-
}
|
|
58
|
-
export type NewAgentRecord = Pick<AgentRecord, 'id' | 'tenantId' | 'slug' | 'name' | 'systemPrompt'> & Partial<Omit<AgentRecord, 'id' | 'tenantId' | 'slug' | 'name' | 'systemPrompt' | 'createdAt' | 'updatedAt'>>;
|
|
59
|
-
export type AgentRecordPatch = Partial<Omit<AgentRecord, 'id' | 'tenantId' | 'createdAt' | 'updatedAt'>>;
|
package/dist/domain/agent.js
DELETED
package/dist/domain/api-key.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Long-lived secret a tenant uses to authenticate machine-to-machine. Format:
|
|
3
|
-
* ak_live_<48 hex chars> (192 bits of entropy)
|
|
4
|
-
*
|
|
5
|
-
* The full key is shown to the user ONLY at creation time. We store the
|
|
6
|
-
* sha256 hash. The first 16 chars (`ak_live_a1b2c3d4`) are kept in plaintext
|
|
7
|
-
* as a `keyPrefix` so users can identify which key in their dashboard.
|
|
8
|
-
*
|
|
9
|
-
* The `ak_live_` prefix is intentional — GitHub secret-scanning, Datadog and
|
|
10
|
-
* similar tools detect leaked credentials by prefix.
|
|
11
|
-
*/
|
|
12
|
-
export interface ApiKey {
|
|
13
|
-
id: string;
|
|
14
|
-
tenantId: string;
|
|
15
|
-
/** When set, the key only authorizes calls to this specific agent. NULL
|
|
16
|
-
* means tenant-wide — any agent in the tenant resolves. */
|
|
17
|
-
agentId?: string;
|
|
18
|
-
name: string;
|
|
19
|
-
keyHash: string;
|
|
20
|
-
keyPrefix: string;
|
|
21
|
-
scopes?: string[];
|
|
22
|
-
expiresAt?: Date;
|
|
23
|
-
revokedAt?: Date;
|
|
24
|
-
lastUsedAt?: Date;
|
|
25
|
-
createdAt: Date;
|
|
26
|
-
}
|
|
27
|
-
export type NewApiKey = Omit<ApiKey, 'id' | 'createdAt' | 'lastUsedAt'>;
|
|
28
|
-
export type ApiKeyPatch = Partial<Pick<ApiKey, 'lastUsedAt' | 'revokedAt' | 'expiresAt' | 'name'>>;
|
package/dist/domain/api-key.js
DELETED