@mastra/factory 0.1.0-alpha.2 → 0.1.0-alpha.4
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/CHANGELOG.md +46 -0
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +812 -209
- package/dist/factory.js.map +1 -1
- package/dist/index.js +812 -209
- package/dist/index.js.map +1 -1
- package/dist/integrations/github/integration.d.ts +2 -2
- package/dist/integrations/github/integration.js +45 -11
- package/dist/integrations/github/integration.js.map +1 -1
- package/dist/integrations/github/provenance.js.map +1 -1
- package/dist/integrations/github/routes.d.ts.map +1 -1
- package/dist/integrations/github/routes.js +12 -9
- package/dist/integrations/github/routes.js.map +1 -1
- package/dist/integrations/github/sandbox.d.ts +1 -0
- package/dist/integrations/github/sandbox.d.ts.map +1 -1
- package/dist/integrations/github/sandbox.js +2 -2
- package/dist/integrations/github/sandbox.js.map +1 -1
- package/dist/integrations/github/session-subscriptions.d.ts +3 -0
- package/dist/integrations/github/session-subscriptions.d.ts.map +1 -1
- package/dist/integrations/github/session-subscriptions.js +30 -0
- package/dist/integrations/github/session-subscriptions.js.map +1 -1
- package/dist/integrations/github/token-refresh.d.ts +6 -0
- package/dist/integrations/github/token-refresh.d.ts.map +1 -0
- package/dist/integrations/github/token-refresh.js +17 -0
- package/dist/integrations/github/token-refresh.js.map +1 -0
- package/dist/integrations/platform/github/event-worker.d.ts +2 -0
- package/dist/integrations/platform/github/event-worker.d.ts.map +1 -1
- package/dist/integrations/platform/github/event-worker.js +8 -0
- package/dist/integrations/platform/github/event-worker.js.map +1 -1
- package/dist/integrations/platform/github/integration.d.ts.map +1 -1
- package/dist/integrations/platform/github/integration.js +52 -9
- package/dist/integrations/platform/github/integration.js.map +1 -1
- package/dist/routes/config.d.ts +16 -11
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +222 -109
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/custom-provider-source.d.ts +52 -0
- package/dist/routes/custom-provider-source.d.ts.map +1 -0
- package/dist/routes/custom-provider-source.js +107 -0
- package/dist/routes/custom-provider-source.js.map +1 -0
- package/dist/routes/oauth.js +33 -1
- package/dist/routes/oauth.js.map +1 -1
- package/dist/routes/surface.d.ts +4 -0
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +282 -111
- package/dist/routes/surface.js.map +1 -1
- package/dist/routes/work-items.js.map +1 -1
- package/dist/rules/defaults.d.ts.map +1 -1
- package/dist/rules/defaults.js +8 -2
- package/dist/rules/defaults.js.map +1 -1
- package/dist/rules/dispatcher.js.map +1 -1
- package/dist/rules/github-service.d.ts +2 -0
- package/dist/rules/github-service.d.ts.map +1 -1
- package/dist/rules/github-service.js +15 -1
- package/dist/rules/github-service.js.map +1 -1
- package/dist/rules/index.js +8 -2
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/linear-service.js.map +1 -1
- package/dist/rules/processor.js.map +1 -1
- package/dist/rules/tools.js.map +1 -1
- package/dist/rules/transition-service.js.map +1 -1
- package/dist/rules/types.d.ts +5 -0
- package/dist/rules/types.d.ts.map +1 -1
- package/dist/rules/types.js.map +1 -1
- package/dist/rules/validation.js.map +1 -1
- package/dist/sandbox/fleet.d.ts +3 -0
- package/dist/sandbox/fleet.d.ts.map +1 -1
- package/dist/sandbox/fleet.js +10 -3
- package/dist/sandbox/fleet.js.map +1 -1
- package/dist/spa-static.d.ts +4 -5
- package/dist/spa-static.d.ts.map +1 -1
- package/dist/spa-static.js +5 -2
- package/dist/spa-static.js.map +1 -1
- package/dist/storage/domains/custom-providers/base.d.ts +57 -0
- package/dist/storage/domains/custom-providers/base.d.ts.map +1 -0
- package/dist/storage/domains/custom-providers/base.js +150 -0
- package/dist/storage/domains/custom-providers/base.js.map +1 -0
- package/dist/storage/domains/memory-settings/base.d.ts +62 -0
- package/dist/storage/domains/memory-settings/base.d.ts.map +1 -0
- package/dist/storage/domains/memory-settings/base.js +111 -0
- package/dist/storage/domains/memory-settings/base.js.map +1 -0
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +17 -0
- package/dist/workspace.js.map +1 -1
- package/package.json +7 -6
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// src/storage/domains/custom-providers/base.ts
|
|
2
|
+
import { FactoryStorageDomain, UniqueViolationError } from "@mastra/core/storage";
|
|
3
|
+
var CUSTOM_PROVIDERS_SCHEMA = {
|
|
4
|
+
name: "custom_providers",
|
|
5
|
+
columns: {
|
|
6
|
+
id: { type: "uuid-pk" },
|
|
7
|
+
org_id: { type: "text" },
|
|
8
|
+
created_by: { type: "text" },
|
|
9
|
+
provider_id: { type: "text" },
|
|
10
|
+
name: { type: "text" },
|
|
11
|
+
url: { type: "text" },
|
|
12
|
+
api_key: { type: "text", nullable: true },
|
|
13
|
+
models: { type: "json" },
|
|
14
|
+
created_at: { type: "timestamp" },
|
|
15
|
+
updated_at: { type: "timestamp" }
|
|
16
|
+
},
|
|
17
|
+
uniqueIndexes: [{ name: "custom_providers_org_provider_key", columns: ["org_id", "provider_id"] }]
|
|
18
|
+
};
|
|
19
|
+
function toRecord(row) {
|
|
20
|
+
return {
|
|
21
|
+
id: row.id,
|
|
22
|
+
orgId: row.org_id,
|
|
23
|
+
createdBy: row.created_by,
|
|
24
|
+
providerId: row.provider_id,
|
|
25
|
+
name: row.name,
|
|
26
|
+
url: row.url,
|
|
27
|
+
apiKey: row.api_key,
|
|
28
|
+
models: Array.isArray(row.models) ? row.models : [],
|
|
29
|
+
createdAt: row.created_at,
|
|
30
|
+
updatedAt: row.updated_at
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
var CustomProvidersStorage = class extends FactoryStorageDomain {
|
|
34
|
+
constructor() {
|
|
35
|
+
super("custom-providers");
|
|
36
|
+
}
|
|
37
|
+
async init() {
|
|
38
|
+
await this.ensureCollections([CUSTOM_PROVIDERS_SCHEMA]);
|
|
39
|
+
}
|
|
40
|
+
async dangerouslyClearAll() {
|
|
41
|
+
await this.ops.deleteMany("custom_providers", {});
|
|
42
|
+
}
|
|
43
|
+
get #db() {
|
|
44
|
+
return this.ops;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Create or wholesale-replace a provider by `(orgId, providerId)` — mirrors
|
|
48
|
+
* the settings.json upsert semantics (no key retention: an absent `apiKey`
|
|
49
|
+
* clears the stored key). `previousProviderId` renames the provider: the
|
|
50
|
+
* common path is a single atomic in-place update of the old row; renaming
|
|
51
|
+
* onto an id that already exists overwrites the target first and removes the
|
|
52
|
+
* old row last, so no interleaving or failure can lose the provider.
|
|
53
|
+
*/
|
|
54
|
+
async upsert({
|
|
55
|
+
orgId,
|
|
56
|
+
userId,
|
|
57
|
+
input,
|
|
58
|
+
previousProviderId
|
|
59
|
+
}) {
|
|
60
|
+
const now = /* @__PURE__ */ new Date();
|
|
61
|
+
const renameFrom = previousProviderId && previousProviderId !== input.providerId ? previousProviderId : void 0;
|
|
62
|
+
if (renameFrom) {
|
|
63
|
+
const target = await this.#db.findOne("custom_providers", {
|
|
64
|
+
org_id: orgId,
|
|
65
|
+
provider_id: input.providerId
|
|
66
|
+
});
|
|
67
|
+
if (!target) {
|
|
68
|
+
const renamed = await this.#db.updateAtomic(
|
|
69
|
+
"custom_providers",
|
|
70
|
+
{ org_id: orgId, provider_id: renameFrom },
|
|
71
|
+
() => ({
|
|
72
|
+
provider_id: input.providerId,
|
|
73
|
+
name: input.name,
|
|
74
|
+
url: input.url,
|
|
75
|
+
api_key: input.apiKey ?? null,
|
|
76
|
+
models: input.models,
|
|
77
|
+
updated_at: now
|
|
78
|
+
})
|
|
79
|
+
);
|
|
80
|
+
if (renamed) return toRecord(renamed);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const record = await this.#write({ orgId, userId, input, now });
|
|
84
|
+
if (renameFrom) {
|
|
85
|
+
await this.#db.deleteMany("custom_providers", { org_id: orgId, provider_id: renameFrom });
|
|
86
|
+
}
|
|
87
|
+
return record;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Update-first, then insert-and-catch-unique-violation (see `queue_health`):
|
|
91
|
+
* concurrent creates of the same provider both succeed (last write wins on
|
|
92
|
+
* the single row) instead of one failing on the unique index, and a row
|
|
93
|
+
* deleted mid-flight is recreated rather than reported as a stale success.
|
|
94
|
+
*/
|
|
95
|
+
async #write({
|
|
96
|
+
orgId,
|
|
97
|
+
userId,
|
|
98
|
+
input,
|
|
99
|
+
now
|
|
100
|
+
}) {
|
|
101
|
+
const updateExisting = () => this.#db.updateAtomic(
|
|
102
|
+
"custom_providers",
|
|
103
|
+
{ org_id: orgId, provider_id: input.providerId },
|
|
104
|
+
() => ({
|
|
105
|
+
name: input.name,
|
|
106
|
+
url: input.url,
|
|
107
|
+
api_key: input.apiKey ?? null,
|
|
108
|
+
models: input.models,
|
|
109
|
+
updated_at: now
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
const updated = await updateExisting();
|
|
113
|
+
if (updated) return toRecord(updated);
|
|
114
|
+
try {
|
|
115
|
+
const row = await this.#db.insertOne("custom_providers", {
|
|
116
|
+
org_id: orgId,
|
|
117
|
+
created_by: userId,
|
|
118
|
+
provider_id: input.providerId,
|
|
119
|
+
name: input.name,
|
|
120
|
+
url: input.url,
|
|
121
|
+
api_key: input.apiKey ?? null,
|
|
122
|
+
models: input.models,
|
|
123
|
+
created_at: now,
|
|
124
|
+
updated_at: now
|
|
125
|
+
});
|
|
126
|
+
return toRecord(row);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
if (!(error instanceof UniqueViolationError)) throw error;
|
|
129
|
+
const row = await updateExisting();
|
|
130
|
+
if (!row) throw error;
|
|
131
|
+
return toRecord(row);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async list({ orgId }) {
|
|
135
|
+
const rows = await this.#db.findMany(
|
|
136
|
+
"custom_providers",
|
|
137
|
+
{ org_id: orgId },
|
|
138
|
+
{ orderBy: [["name", "asc"]] }
|
|
139
|
+
);
|
|
140
|
+
return rows.map(toRecord);
|
|
141
|
+
}
|
|
142
|
+
async delete({ orgId, providerId }) {
|
|
143
|
+
return await this.#db.deleteMany("custom_providers", { org_id: orgId, provider_id: providerId }) > 0;
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
export {
|
|
147
|
+
CUSTOM_PROVIDERS_SCHEMA,
|
|
148
|
+
CustomProvidersStorage
|
|
149
|
+
};
|
|
150
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/storage/domains/custom-providers/base.ts"],"sourcesContent":["import { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\n/**\n * A user-defined OpenAI-compatible provider. The DB-backed counterpart of the\n * local `settings.json` `customProviders` entries: org-scoped rows keyed by the\n * derived provider id (name slug), API key stored alongside so a deployed\n * server never reads the shared settings file.\n */\nexport interface CustomProviderRecord {\n id: string;\n orgId: string;\n createdBy: string;\n /** Stable slug derived from the name (`getCustomProviderId`). */\n providerId: string;\n name: string;\n url: string;\n apiKey: string | null;\n models: string[];\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface UpsertCustomProviderInput {\n providerId: string;\n name: string;\n url: string;\n apiKey?: string;\n models: string[];\n}\n\nexport const CUSTOM_PROVIDERS_SCHEMA: CollectionSchema = {\n name: 'custom_providers',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n created_by: { type: 'text' },\n provider_id: { type: 'text' },\n name: { type: 'text' },\n url: { type: 'text' },\n api_key: { type: 'text', nullable: true },\n models: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'custom_providers_org_provider_key', columns: ['org_id', 'provider_id'] }],\n};\n\ninterface CustomProviderDbRow extends Record<string, unknown> {\n id: string;\n org_id: string;\n created_by: string;\n provider_id: string;\n name: string;\n url: string;\n api_key: string | null;\n models: string[];\n created_at: Date;\n updated_at: Date;\n}\n\nfunction toRecord(row: CustomProviderDbRow): CustomProviderRecord {\n return {\n id: row.id,\n orgId: row.org_id,\n createdBy: row.created_by,\n providerId: row.provider_id,\n name: row.name,\n url: row.url,\n apiKey: row.api_key,\n models: Array.isArray(row.models) ? row.models : [],\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nexport class CustomProvidersStorage extends FactoryStorageDomain {\n constructor() {\n super('custom-providers');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([CUSTOM_PROVIDERS_SCHEMA]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('custom_providers', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n /**\n * Create or wholesale-replace a provider by `(orgId, providerId)` — mirrors\n * the settings.json upsert semantics (no key retention: an absent `apiKey`\n * clears the stored key). `previousProviderId` renames the provider: the\n * common path is a single atomic in-place update of the old row; renaming\n * onto an id that already exists overwrites the target first and removes the\n * old row last, so no interleaving or failure can lose the provider.\n */\n async upsert({\n orgId,\n userId,\n input,\n previousProviderId,\n }: {\n orgId: string;\n userId: string;\n input: UpsertCustomProviderInput;\n previousProviderId?: string;\n }): Promise<CustomProviderRecord> {\n const now = new Date();\n const renameFrom = previousProviderId && previousProviderId !== input.providerId ? previousProviderId : undefined;\n\n if (renameFrom) {\n const target = await this.#db.findOne<CustomProviderDbRow>('custom_providers', {\n org_id: orgId,\n provider_id: input.providerId,\n });\n if (!target) {\n // In-place rename: one atomic write with no delete/insert gap, so a\n // failure can never drop the provider (and `created_at`/`created_by`\n // are preserved). If a concurrent create grabs the new id between the\n // lookup and this update, the unique index rejects the update and the\n // old row stays intact — the request fails cleanly and a retry\n // converges on the rename-onto-existing path below.\n const renamed = await this.#db.updateAtomic<CustomProviderDbRow>(\n 'custom_providers',\n { org_id: orgId, provider_id: renameFrom },\n () => ({\n provider_id: input.providerId,\n name: input.name,\n url: input.url,\n api_key: input.apiKey ?? null,\n models: input.models,\n updated_at: now,\n }),\n );\n if (renamed) return toRecord(renamed);\n // Old row already gone — fall through to a plain create of the new id.\n }\n // Rename onto an existing id: overwrite the target below, then delete\n // the old row last — a failure in the gap leaves a redundant duplicate\n // (recoverable by re-submitting or deleting) instead of losing data.\n }\n\n const record = await this.#write({ orgId, userId, input, now });\n if (renameFrom) {\n await this.#db.deleteMany('custom_providers', { org_id: orgId, provider_id: renameFrom });\n }\n return record;\n }\n\n /**\n * Update-first, then insert-and-catch-unique-violation (see `queue_health`):\n * concurrent creates of the same provider both succeed (last write wins on\n * the single row) instead of one failing on the unique index, and a row\n * deleted mid-flight is recreated rather than reported as a stale success.\n */\n async #write({\n orgId,\n userId,\n input,\n now,\n }: {\n orgId: string;\n userId: string;\n input: UpsertCustomProviderInput;\n now: Date;\n }): Promise<CustomProviderRecord> {\n const updateExisting = () =>\n this.#db.updateAtomic<CustomProviderDbRow>(\n 'custom_providers',\n { org_id: orgId, provider_id: input.providerId },\n () => ({\n name: input.name,\n url: input.url,\n api_key: input.apiKey ?? null,\n models: input.models,\n updated_at: now,\n }),\n );\n\n const updated = await updateExisting();\n if (updated) return toRecord(updated);\n\n try {\n const row = await this.#db.insertOne<CustomProviderDbRow>('custom_providers', {\n org_id: orgId,\n created_by: userId,\n provider_id: input.providerId,\n name: input.name,\n url: input.url,\n api_key: input.apiKey ?? null,\n models: input.models,\n created_at: now,\n updated_at: now,\n });\n return toRecord(row);\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n // Lost the insert race — apply this write to the winning row.\n const row = await updateExisting();\n if (!row) throw error;\n return toRecord(row);\n }\n }\n\n async list({ orgId }: { orgId: string }): Promise<CustomProviderRecord[]> {\n const rows = await this.#db.findMany<CustomProviderDbRow>(\n 'custom_providers',\n { org_id: orgId },\n { orderBy: [['name', 'asc']] },\n );\n return rows.map(toRecord);\n }\n\n async delete({ orgId, providerId }: { orgId: string; providerId: string }): Promise<boolean> {\n return (await this.#db.deleteMany('custom_providers', { org_id: orgId, provider_id: providerId })) > 0;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { FactoryStorageDomain } from '@mastra/core/storage';
|
|
2
|
+
import type { CollectionSchema } from '@mastra/core/storage';
|
|
3
|
+
/**
|
|
4
|
+
* A user's persisted memory (observational-memory) configuration. The
|
|
5
|
+
* DB-backed tenant counterpart of the local `settings.json` OM fields
|
|
6
|
+
* (`observerModelOverride`, `reflectorModelOverride`, `omObservationThreshold`,
|
|
7
|
+
* `omReflectionThreshold`, `omObserveAttachments`): one row per `(org, user)`,
|
|
8
|
+
* every knob nullable so only explicitly-changed values are stored.
|
|
9
|
+
*/
|
|
10
|
+
export interface MemorySettingsRecord {
|
|
11
|
+
orgId: string;
|
|
12
|
+
userId: string;
|
|
13
|
+
observerModelId: string | null;
|
|
14
|
+
reflectorModelId: string | null;
|
|
15
|
+
observationThreshold: number | null;
|
|
16
|
+
reflectionThreshold: number | null;
|
|
17
|
+
observeAttachments: 'auto' | boolean | null;
|
|
18
|
+
createdAt: Date;
|
|
19
|
+
updatedAt: Date;
|
|
20
|
+
}
|
|
21
|
+
/** Partial update — only the provided knobs are written. */
|
|
22
|
+
export interface MemorySettingsPatch {
|
|
23
|
+
observerModelId?: string;
|
|
24
|
+
reflectorModelId?: string;
|
|
25
|
+
observationThreshold?: number;
|
|
26
|
+
reflectionThreshold?: number;
|
|
27
|
+
observeAttachments?: 'auto' | boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Knobs written only when the stored value is still unset (`NULL`). The check
|
|
31
|
+
* happens inside the backend's atomic-update primitive, so a concurrent
|
|
32
|
+
* explicit write to the same knob is never clobbered by a fill.
|
|
33
|
+
*/
|
|
34
|
+
export interface MemorySettingsFillIfUnset {
|
|
35
|
+
observerModelId?: string;
|
|
36
|
+
reflectorModelId?: string;
|
|
37
|
+
}
|
|
38
|
+
export declare const MEMORY_SETTINGS_SCHEMA: CollectionSchema;
|
|
39
|
+
export declare class MemorySettingsStorage extends FactoryStorageDomain {
|
|
40
|
+
#private;
|
|
41
|
+
constructor();
|
|
42
|
+
init(): Promise<void>;
|
|
43
|
+
dangerouslyClearAll(): Promise<void>;
|
|
44
|
+
get({ orgId, userId }: {
|
|
45
|
+
orgId: string;
|
|
46
|
+
userId: string;
|
|
47
|
+
}): Promise<MemorySettingsRecord | null>;
|
|
48
|
+
/**
|
|
49
|
+
* Upsert the user's row, writing only the knobs present in `patch`.
|
|
50
|
+
* `fillIfUnset` knobs are written only where the stored value is still
|
|
51
|
+
* `NULL`, decided inside the atomic update so concurrent explicit writes
|
|
52
|
+
* win over fills. Concurrent first writes are resolved via the shared
|
|
53
|
+
* insert-then-catch-unique-violation pattern (see `queue_health`).
|
|
54
|
+
*/
|
|
55
|
+
patch({ orgId, userId, patch, fillIfUnset, }: {
|
|
56
|
+
orgId: string;
|
|
57
|
+
userId: string;
|
|
58
|
+
patch: MemorySettingsPatch;
|
|
59
|
+
fillIfUnset?: MemorySettingsFillIfUnset;
|
|
60
|
+
}): Promise<MemorySettingsRecord>;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/memory-settings/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAwB,MAAM,sBAAsB,CAAC;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAqB,MAAM,sBAAsB,CAAC;AAEhF;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,kBAAkB,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IAC5C,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,4DAA4D;AAC5D,MAAM,WAAW,mBAAmB;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACvC;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,sBAAsB,EAAE,gBAgBpC,CAAC;AAuCF,qBAAa,qBAAsB,SAAQ,oBAAoB;;;IAKvD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAQpC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAKrG;;;;;;OAMG;IACG,KAAK,CAAC,EACV,KAAK,EACL,MAAM,EACN,KAAK,EACL,WAAW,GACZ,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,mBAAmB,CAAC;QAC3B,WAAW,CAAC,EAAE,yBAAyB,CAAC;KACzC,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAuClC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// src/storage/domains/memory-settings/base.ts
|
|
2
|
+
import { FactoryStorageDomain, UniqueViolationError } from "@mastra/core/storage";
|
|
3
|
+
var MEMORY_SETTINGS_SCHEMA = {
|
|
4
|
+
name: "memory_settings",
|
|
5
|
+
columns: {
|
|
6
|
+
id: { type: "uuid-pk" },
|
|
7
|
+
org_id: { type: "text" },
|
|
8
|
+
user_id: { type: "text" },
|
|
9
|
+
observer_model_id: { type: "text", nullable: true },
|
|
10
|
+
reflector_model_id: { type: "text", nullable: true },
|
|
11
|
+
observation_threshold: { type: "integer", nullable: true },
|
|
12
|
+
reflection_threshold: { type: "integer", nullable: true },
|
|
13
|
+
// 'auto' | true | false — json keeps the tri-state without string encoding.
|
|
14
|
+
observe_attachments: { type: "json", nullable: true },
|
|
15
|
+
created_at: { type: "timestamp" },
|
|
16
|
+
updated_at: { type: "timestamp" }
|
|
17
|
+
},
|
|
18
|
+
uniqueIndexes: [{ name: "memory_settings_org_user_key", columns: ["org_id", "user_id"] }]
|
|
19
|
+
};
|
|
20
|
+
function toRecord(row) {
|
|
21
|
+
return {
|
|
22
|
+
orgId: row.org_id,
|
|
23
|
+
userId: row.user_id,
|
|
24
|
+
observerModelId: row.observer_model_id,
|
|
25
|
+
reflectorModelId: row.reflector_model_id,
|
|
26
|
+
observationThreshold: row.observation_threshold,
|
|
27
|
+
reflectionThreshold: row.reflection_threshold,
|
|
28
|
+
observeAttachments: row.observe_attachments,
|
|
29
|
+
createdAt: row.created_at,
|
|
30
|
+
updatedAt: row.updated_at
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function patchToColumns(patch) {
|
|
34
|
+
const columns = {};
|
|
35
|
+
if (patch.observerModelId !== void 0) columns.observer_model_id = patch.observerModelId;
|
|
36
|
+
if (patch.reflectorModelId !== void 0) columns.reflector_model_id = patch.reflectorModelId;
|
|
37
|
+
if (patch.observationThreshold !== void 0) columns.observation_threshold = patch.observationThreshold;
|
|
38
|
+
if (patch.reflectionThreshold !== void 0) columns.reflection_threshold = patch.reflectionThreshold;
|
|
39
|
+
if (patch.observeAttachments !== void 0) columns.observe_attachments = patch.observeAttachments;
|
|
40
|
+
return columns;
|
|
41
|
+
}
|
|
42
|
+
var MemorySettingsStorage = class extends FactoryStorageDomain {
|
|
43
|
+
constructor() {
|
|
44
|
+
super("memory-settings");
|
|
45
|
+
}
|
|
46
|
+
async init() {
|
|
47
|
+
await this.ensureCollections([MEMORY_SETTINGS_SCHEMA]);
|
|
48
|
+
}
|
|
49
|
+
async dangerouslyClearAll() {
|
|
50
|
+
await this.ops.deleteMany("memory_settings", {});
|
|
51
|
+
}
|
|
52
|
+
get #db() {
|
|
53
|
+
return this.ops;
|
|
54
|
+
}
|
|
55
|
+
async get({ orgId, userId }) {
|
|
56
|
+
const row = await this.#db.findOne("memory_settings", { org_id: orgId, user_id: userId });
|
|
57
|
+
return row ? toRecord(row) : null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Upsert the user's row, writing only the knobs present in `patch`.
|
|
61
|
+
* `fillIfUnset` knobs are written only where the stored value is still
|
|
62
|
+
* `NULL`, decided inside the atomic update so concurrent explicit writes
|
|
63
|
+
* win over fills. Concurrent first writes are resolved via the shared
|
|
64
|
+
* insert-then-catch-unique-violation pattern (see `queue_health`).
|
|
65
|
+
*/
|
|
66
|
+
async patch({
|
|
67
|
+
orgId,
|
|
68
|
+
userId,
|
|
69
|
+
patch,
|
|
70
|
+
fillIfUnset
|
|
71
|
+
}) {
|
|
72
|
+
const now = /* @__PURE__ */ new Date();
|
|
73
|
+
const updateExisting = () => this.#db.updateAtomic("memory_settings", { org_id: orgId, user_id: userId }, (row) => {
|
|
74
|
+
const columns = { ...patchToColumns(patch), updated_at: now };
|
|
75
|
+
if (fillIfUnset?.observerModelId !== void 0 && row.observer_model_id == null) {
|
|
76
|
+
columns.observer_model_id = patch.observerModelId ?? fillIfUnset.observerModelId;
|
|
77
|
+
}
|
|
78
|
+
if (fillIfUnset?.reflectorModelId !== void 0 && row.reflector_model_id == null) {
|
|
79
|
+
columns.reflector_model_id = patch.reflectorModelId ?? fillIfUnset.reflectorModelId;
|
|
80
|
+
}
|
|
81
|
+
return columns;
|
|
82
|
+
});
|
|
83
|
+
const updated = await updateExisting();
|
|
84
|
+
if (updated) return toRecord(updated);
|
|
85
|
+
try {
|
|
86
|
+
const row = await this.#db.insertOne("memory_settings", {
|
|
87
|
+
org_id: orgId,
|
|
88
|
+
user_id: userId,
|
|
89
|
+
observer_model_id: fillIfUnset?.observerModelId ?? null,
|
|
90
|
+
reflector_model_id: fillIfUnset?.reflectorModelId ?? null,
|
|
91
|
+
observation_threshold: null,
|
|
92
|
+
reflection_threshold: null,
|
|
93
|
+
observe_attachments: null,
|
|
94
|
+
...patchToColumns(patch),
|
|
95
|
+
created_at: now,
|
|
96
|
+
updated_at: now
|
|
97
|
+
});
|
|
98
|
+
return toRecord(row);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
if (!(error instanceof UniqueViolationError)) throw error;
|
|
101
|
+
const row = await updateExisting();
|
|
102
|
+
if (!row) throw error;
|
|
103
|
+
return toRecord(row);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
export {
|
|
108
|
+
MEMORY_SETTINGS_SCHEMA,
|
|
109
|
+
MemorySettingsStorage
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/storage/domains/memory-settings/base.ts"],"sourcesContent":["import { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\n/**\n * A user's persisted memory (observational-memory) configuration. The\n * DB-backed tenant counterpart of the local `settings.json` OM fields\n * (`observerModelOverride`, `reflectorModelOverride`, `omObservationThreshold`,\n * `omReflectionThreshold`, `omObserveAttachments`): one row per `(org, user)`,\n * every knob nullable so only explicitly-changed values are stored.\n */\nexport interface MemorySettingsRecord {\n orgId: string;\n userId: string;\n observerModelId: string | null;\n reflectorModelId: string | null;\n observationThreshold: number | null;\n reflectionThreshold: number | null;\n observeAttachments: 'auto' | boolean | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/** Partial update — only the provided knobs are written. */\nexport interface MemorySettingsPatch {\n observerModelId?: string;\n reflectorModelId?: string;\n observationThreshold?: number;\n reflectionThreshold?: number;\n observeAttachments?: 'auto' | boolean;\n}\n\n/**\n * Knobs written only when the stored value is still unset (`NULL`). The check\n * happens inside the backend's atomic-update primitive, so a concurrent\n * explicit write to the same knob is never clobbered by a fill.\n */\nexport interface MemorySettingsFillIfUnset {\n observerModelId?: string;\n reflectorModelId?: string;\n}\n\nexport const MEMORY_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'memory_settings',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n observer_model_id: { type: 'text', nullable: true },\n reflector_model_id: { type: 'text', nullable: true },\n observation_threshold: { type: 'integer', nullable: true },\n reflection_threshold: { type: 'integer', nullable: true },\n // 'auto' | true | false — json keeps the tri-state without string encoding.\n observe_attachments: { type: 'json', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'memory_settings_org_user_key', columns: ['org_id', 'user_id'] }],\n};\n\ninterface MemorySettingsDbRow extends Record<string, unknown> {\n id: string;\n org_id: string;\n user_id: string;\n observer_model_id: string | null;\n reflector_model_id: string | null;\n observation_threshold: number | null;\n reflection_threshold: number | null;\n observe_attachments: 'auto' | boolean | null;\n created_at: Date;\n updated_at: Date;\n}\n\nfunction toRecord(row: MemorySettingsDbRow): MemorySettingsRecord {\n return {\n orgId: row.org_id,\n userId: row.user_id,\n observerModelId: row.observer_model_id,\n reflectorModelId: row.reflector_model_id,\n observationThreshold: row.observation_threshold,\n reflectionThreshold: row.reflection_threshold,\n observeAttachments: row.observe_attachments,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction patchToColumns(patch: MemorySettingsPatch): Partial<MemorySettingsDbRow> {\n const columns: Partial<MemorySettingsDbRow> = {};\n if (patch.observerModelId !== undefined) columns.observer_model_id = patch.observerModelId;\n if (patch.reflectorModelId !== undefined) columns.reflector_model_id = patch.reflectorModelId;\n if (patch.observationThreshold !== undefined) columns.observation_threshold = patch.observationThreshold;\n if (patch.reflectionThreshold !== undefined) columns.reflection_threshold = patch.reflectionThreshold;\n if (patch.observeAttachments !== undefined) columns.observe_attachments = patch.observeAttachments;\n return columns;\n}\n\nexport class MemorySettingsStorage extends FactoryStorageDomain {\n constructor() {\n super('memory-settings');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([MEMORY_SETTINGS_SCHEMA]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('memory_settings', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async get({ orgId, userId }: { orgId: string; userId: string }): Promise<MemorySettingsRecord | null> {\n const row = await this.#db.findOne<MemorySettingsDbRow>('memory_settings', { org_id: orgId, user_id: userId });\n return row ? toRecord(row) : null;\n }\n\n /**\n * Upsert the user's row, writing only the knobs present in `patch`.\n * `fillIfUnset` knobs are written only where the stored value is still\n * `NULL`, decided inside the atomic update so concurrent explicit writes\n * win over fills. Concurrent first writes are resolved via the shared\n * insert-then-catch-unique-violation pattern (see `queue_health`).\n */\n async patch({\n orgId,\n userId,\n patch,\n fillIfUnset,\n }: {\n orgId: string;\n userId: string;\n patch: MemorySettingsPatch;\n fillIfUnset?: MemorySettingsFillIfUnset;\n }): Promise<MemorySettingsRecord> {\n const now = new Date();\n const updateExisting = () =>\n this.#db.updateAtomic<MemorySettingsDbRow>('memory_settings', { org_id: orgId, user_id: userId }, row => {\n const columns: Partial<MemorySettingsDbRow> = { ...patchToColumns(patch), updated_at: now };\n if (fillIfUnset?.observerModelId !== undefined && row.observer_model_id == null) {\n columns.observer_model_id = patch.observerModelId ?? fillIfUnset.observerModelId;\n }\n if (fillIfUnset?.reflectorModelId !== undefined && row.reflector_model_id == null) {\n columns.reflector_model_id = patch.reflectorModelId ?? fillIfUnset.reflectorModelId;\n }\n return columns;\n });\n\n const updated = await updateExisting();\n if (updated) return toRecord(updated);\n\n try {\n const row = await this.#db.insertOne<MemorySettingsDbRow>('memory_settings', {\n org_id: orgId,\n user_id: userId,\n observer_model_id: fillIfUnset?.observerModelId ?? null,\n reflector_model_id: fillIfUnset?.reflectorModelId ?? null,\n observation_threshold: null,\n reflection_threshold: null,\n observe_attachments: null,\n ...patchToColumns(patch),\n created_at: now,\n updated_at: now,\n });\n return toRecord(row);\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n // Lost the first-write race — apply the patch to the winning row.\n const row = await updateExisting();\n if (!row) throw error;\n return toRecord(row);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/workspace.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAE/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAKxE,OAAO,EAAE,YAAY,EAAoB,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAInF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAE/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAKxE,OAAO,EAAE,YAAY,EAAoB,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAInF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAG9E,OAAO,KAAK,EAAuB,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAK5E,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAElE;AA+ED,KAAK,uBAAuB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzE,MAAM,WAAW,6BAA6B;IAC5C,wEAAwE;IACxE,OAAO,CAAC,EAAE,0BAA0B,CAAC;IACrC,gFAAgF;IAChF,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,0EAA0E;IAC1E,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,6BAAkC,IAKlE,4CAA4C,uBAAuB,wVAqHlF;AAED,eAAO,MAAM,mBAAmB,+CAvH4B,uBAAuB,uVAuHxB,CAAC"}
|
package/dist/workspace.js
CHANGED
|
@@ -193,6 +193,12 @@ async function runWorktreeSetup(sandbox, worktreePath, command) {
|
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
+
// src/integrations/github/token-refresh.ts
|
|
197
|
+
var GITHUB_TOKEN_INJECTOR_CONTEXT_KEY = "factoryGithubTokenInjector";
|
|
198
|
+
function registerGithubTokenInjector(requestContext, injector) {
|
|
199
|
+
requestContext.set(GITHUB_TOKEN_INJECTOR_CONTEXT_KEY, injector);
|
|
200
|
+
}
|
|
201
|
+
|
|
196
202
|
// src/workspace.ts
|
|
197
203
|
var WORKSPACE_ID_PREFIX = "mfw";
|
|
198
204
|
var SESSION_CHECKPOINT_PREFIX = "mastracode-session";
|
|
@@ -260,6 +266,7 @@ var factorySkillExtension = {
|
|
|
260
266
|
function createWorkspaceFactory(options = {}) {
|
|
261
267
|
const { sandbox: sandboxConfig, github, fleet } = options;
|
|
262
268
|
const isLocalSandbox = sandboxConfig?.machine instanceof LocalSandbox;
|
|
269
|
+
const githubTokenInjectors = /* @__PURE__ */ new Map();
|
|
263
270
|
return async ({ requestContext, mastra, skillExtension }) => {
|
|
264
271
|
const effectiveSkillExtension = skillExtension ?? factorySkillExtension;
|
|
265
272
|
const ctx = requestContext.get("controller");
|
|
@@ -311,6 +318,8 @@ function createWorkspaceFactory(options = {}) {
|
|
|
311
318
|
const existing = mastra?.getWorkspaceById(workspaceId);
|
|
312
319
|
if (existing) {
|
|
313
320
|
existing.setToolsConfig(MASTRACODE_WORKSPACE_TOOLS);
|
|
321
|
+
const injectGithubToken2 = githubTokenInjectors.get(workspaceId);
|
|
322
|
+
if (injectGithubToken2) registerGithubTokenInjector(requestContext, injectGithubToken2);
|
|
314
323
|
return existing;
|
|
315
324
|
}
|
|
316
325
|
} catch {
|
|
@@ -341,6 +350,14 @@ function createWorkspaceFactory(options = {}) {
|
|
|
341
350
|
repoFullName
|
|
342
351
|
});
|
|
343
352
|
if (projectRepository.setupCommand) await runWorktreeSetup(sandbox, workdir, projectRepository.setupCommand);
|
|
353
|
+
const injectGithubToken = (freshToken) => {
|
|
354
|
+
if (!sandbox.setEnvironmentVariable) {
|
|
355
|
+
throw new Error("The active sandbox provider does not support runtime GitHub token refresh.");
|
|
356
|
+
}
|
|
357
|
+
sandbox.setEnvironmentVariable("GH_TOKEN", freshToken);
|
|
358
|
+
};
|
|
359
|
+
githubTokenInjectors.set(workspaceId, injectGithubToken);
|
|
360
|
+
registerGithubTokenInjector(requestContext, injectGithubToken);
|
|
344
361
|
const filesystem = new SandboxFilesystem({ sandbox, workdir });
|
|
345
362
|
const projectSkillPaths = [path2.join(configDir, "skills"), ".claude/skills", ".agents/skills"];
|
|
346
363
|
const skillPaths = [...effectiveSkillExtension?.paths ?? [], ...projectSkillPaths];
|