@mastra/factory 0.2.0-alpha.0 → 0.2.1-alpha.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/CHANGELOG.md +36 -0
- package/dist/capabilities/intake.d.ts +45 -0
- package/dist/capabilities/intake.d.ts.map +1 -1
- package/dist/factory.js +923 -552
- package/dist/factory.js.map +1 -1
- package/dist/index.js +923 -552
- package/dist/index.js.map +1 -1
- package/dist/integrations/github/integration.d.ts.map +1 -1
- package/dist/integrations/github/integration.js +127 -12
- package/dist/integrations/github/integration.js.map +1 -1
- package/dist/integrations/github/project-lock.d.ts +24 -2
- package/dist/integrations/github/project-lock.d.ts.map +1 -1
- package/dist/integrations/github/project-lock.js +43 -10
- package/dist/integrations/github/project-lock.js.map +1 -1
- package/dist/integrations/github/routes.js +42 -11
- package/dist/integrations/github/routes.js.map +1 -1
- package/dist/integrations/linear/agent-tools.js.map +1 -1
- package/dist/integrations/linear/integration.d.ts.map +1 -1
- package/dist/integrations/linear/integration.js +60 -1
- package/dist/integrations/linear/integration.js.map +1 -1
- package/dist/integrations/linear/routes.js.map +1 -1
- package/dist/integrations/platform/api-client.js +1 -1
- package/dist/integrations/platform/api-client.js.map +1 -1
- package/dist/integrations/platform/github/event-worker.d.ts.map +1 -1
- package/dist/integrations/platform/github/event-worker.js +7 -1
- 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 +106 -14
- package/dist/integrations/platform/github/integration.js.map +1 -1
- package/dist/integrations/platform/linear/integration.d.ts.map +1 -1
- package/dist/integrations/platform/linear/integration.js +92 -1
- package/dist/integrations/platform/linear/integration.js.map +1 -1
- package/dist/routes/fs.d.ts +16 -0
- package/dist/routes/fs.d.ts.map +1 -1
- package/dist/routes/fs.js +103 -3
- package/dist/routes/fs.js.map +1 -1
- package/dist/routes/oauth.js +564 -478
- package/dist/routes/oauth.js.map +1 -1
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +1 -0
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +717 -526
- package/dist/routes/surface.js.map +1 -1
- package/dist/server-error.js +1 -1
- package/dist/server-error.js.map +1 -1
- package/dist/storage/domains/source-control/base.d.ts +0 -1
- package/dist/storage/domains/source-control/base.d.ts.map +1 -1
- package/dist/storage/domains/source-control/base.js +6 -7
- package/dist/storage/domains/source-control/base.js.map +1 -1
- package/package.json +6 -6
package/dist/factory.js
CHANGED
|
@@ -18882,46 +18882,49 @@ Note: This migration may take some time for large tables.
|
|
|
18882
18882
|
config: input.config,
|
|
18883
18883
|
observedTimezone: input.observedTimezone
|
|
18884
18884
|
};
|
|
18885
|
-
await
|
|
18886
|
-
|
|
18887
|
-
|
|
18888
|
-
|
|
18889
|
-
|
|
18890
|
-
|
|
18891
|
-
|
|
18892
|
-
|
|
18893
|
-
|
|
18894
|
-
|
|
18895
|
-
|
|
18896
|
-
|
|
18897
|
-
|
|
18898
|
-
|
|
18899
|
-
|
|
18900
|
-
|
|
18901
|
-
|
|
18902
|
-
|
|
18903
|
-
|
|
18904
|
-
|
|
18905
|
-
|
|
18906
|
-
|
|
18907
|
-
|
|
18908
|
-
|
|
18909
|
-
|
|
18910
|
-
|
|
18911
|
-
|
|
18912
|
-
|
|
18913
|
-
|
|
18914
|
-
|
|
18915
|
-
|
|
18916
|
-
|
|
18917
|
-
|
|
18918
|
-
|
|
18919
|
-
|
|
18920
|
-
|
|
18921
|
-
|
|
18922
|
-
|
|
18923
|
-
|
|
18924
|
-
|
|
18885
|
+
await withClientWriteLock(
|
|
18886
|
+
this.#client,
|
|
18887
|
+
() => this.#client.execute({
|
|
18888
|
+
sql: `INSERT INTO "${OM_TABLE}" (
|
|
18889
|
+
id, "lookupKey", scope, "resourceId", "threadId",
|
|
18890
|
+
"activeObservations", "activeObservationsPendingUpdate",
|
|
18891
|
+
"originType", config, "generationCount", "lastObservedAt", "lastReflectionAt",
|
|
18892
|
+
"pendingMessageTokens", "totalTokensObserved", "observationTokenCount",
|
|
18893
|
+
"isObserving", "isReflecting", "isBufferingObservation", "isBufferingReflection", "lastBufferedAtTokens", "lastBufferedAtTime",
|
|
18894
|
+
"observedTimezone", "createdAt", "updatedAt"
|
|
18895
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
18896
|
+
args: [
|
|
18897
|
+
id,
|
|
18898
|
+
lookupKey,
|
|
18899
|
+
input.scope,
|
|
18900
|
+
input.resourceId,
|
|
18901
|
+
input.threadId || null,
|
|
18902
|
+
"",
|
|
18903
|
+
null,
|
|
18904
|
+
"initial",
|
|
18905
|
+
JSON.stringify(input.config),
|
|
18906
|
+
0,
|
|
18907
|
+
null,
|
|
18908
|
+
null,
|
|
18909
|
+
0,
|
|
18910
|
+
0,
|
|
18911
|
+
0,
|
|
18912
|
+
false,
|
|
18913
|
+
false,
|
|
18914
|
+
false,
|
|
18915
|
+
// isBufferingObservation
|
|
18916
|
+
false,
|
|
18917
|
+
// isBufferingReflection
|
|
18918
|
+
0,
|
|
18919
|
+
// lastBufferedAtTokens
|
|
18920
|
+
null,
|
|
18921
|
+
// lastBufferedAtTime
|
|
18922
|
+
input.observedTimezone || null,
|
|
18923
|
+
now.toISOString(),
|
|
18924
|
+
now.toISOString()
|
|
18925
|
+
]
|
|
18926
|
+
})
|
|
18927
|
+
);
|
|
18925
18928
|
return record;
|
|
18926
18929
|
} catch (error) {
|
|
18927
18930
|
throw new MastraError(
|
|
@@ -18938,53 +18941,56 @@ Note: This migration may take some time for large tables.
|
|
|
18938
18941
|
async insertObservationalMemoryRecord(record) {
|
|
18939
18942
|
try {
|
|
18940
18943
|
const lookupKey = this.getOMKey(record.threadId, record.resourceId);
|
|
18941
|
-
await
|
|
18942
|
-
|
|
18943
|
-
|
|
18944
|
-
|
|
18945
|
-
|
|
18946
|
-
|
|
18947
|
-
|
|
18948
|
-
|
|
18949
|
-
|
|
18950
|
-
|
|
18951
|
-
|
|
18952
|
-
|
|
18953
|
-
|
|
18954
|
-
|
|
18955
|
-
|
|
18956
|
-
|
|
18957
|
-
|
|
18958
|
-
|
|
18959
|
-
|
|
18960
|
-
|
|
18961
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
|
|
18966
|
-
|
|
18967
|
-
|
|
18968
|
-
|
|
18969
|
-
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
18975
|
-
|
|
18976
|
-
|
|
18977
|
-
|
|
18978
|
-
|
|
18979
|
-
|
|
18980
|
-
|
|
18981
|
-
|
|
18982
|
-
|
|
18983
|
-
|
|
18984
|
-
|
|
18985
|
-
|
|
18986
|
-
|
|
18987
|
-
|
|
18944
|
+
await withClientWriteLock(
|
|
18945
|
+
this.#client,
|
|
18946
|
+
() => this.#client.execute({
|
|
18947
|
+
sql: `INSERT INTO "${OM_TABLE}" (
|
|
18948
|
+
id, "lookupKey", scope, "resourceId", "threadId",
|
|
18949
|
+
"activeObservations", "activeObservationsPendingUpdate",
|
|
18950
|
+
"originType", config, "generationCount", "lastObservedAt", "lastReflectionAt",
|
|
18951
|
+
"pendingMessageTokens", "totalTokensObserved", "observationTokenCount",
|
|
18952
|
+
"observedMessageIds", "bufferedObservationChunks",
|
|
18953
|
+
"bufferedReflection", "bufferedReflectionTokens", "bufferedReflectionInputTokens",
|
|
18954
|
+
"reflectedObservationLineCount",
|
|
18955
|
+
"isObserving", "isReflecting", "isBufferingObservation", "isBufferingReflection",
|
|
18956
|
+
"lastBufferedAtTokens", "lastBufferedAtTime",
|
|
18957
|
+
"observedTimezone", metadata, "createdAt", "updatedAt"
|
|
18958
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
18959
|
+
args: [
|
|
18960
|
+
record.id,
|
|
18961
|
+
lookupKey,
|
|
18962
|
+
record.scope,
|
|
18963
|
+
record.resourceId,
|
|
18964
|
+
record.threadId || null,
|
|
18965
|
+
record.activeObservations || "",
|
|
18966
|
+
null,
|
|
18967
|
+
record.originType || "initial",
|
|
18968
|
+
record.config ? JSON.stringify(record.config) : null,
|
|
18969
|
+
record.generationCount || 0,
|
|
18970
|
+
record.lastObservedAt ? record.lastObservedAt.toISOString() : null,
|
|
18971
|
+
null,
|
|
18972
|
+
record.pendingMessageTokens || 0,
|
|
18973
|
+
record.totalTokensObserved || 0,
|
|
18974
|
+
record.observationTokenCount || 0,
|
|
18975
|
+
record.observedMessageIds ? JSON.stringify(record.observedMessageIds) : null,
|
|
18976
|
+
record.bufferedObservationChunks ? JSON.stringify(record.bufferedObservationChunks) : null,
|
|
18977
|
+
record.bufferedReflection || null,
|
|
18978
|
+
record.bufferedReflectionTokens ?? null,
|
|
18979
|
+
record.bufferedReflectionInputTokens ?? null,
|
|
18980
|
+
record.reflectedObservationLineCount ?? null,
|
|
18981
|
+
record.isObserving || false,
|
|
18982
|
+
record.isReflecting || false,
|
|
18983
|
+
record.isBufferingObservation || false,
|
|
18984
|
+
record.isBufferingReflection || false,
|
|
18985
|
+
record.lastBufferedAtTokens || 0,
|
|
18986
|
+
record.lastBufferedAtTime ? record.lastBufferedAtTime.toISOString() : null,
|
|
18987
|
+
record.observedTimezone || null,
|
|
18988
|
+
record.metadata ? JSON.stringify(record.metadata) : null,
|
|
18989
|
+
record.createdAt.toISOString(),
|
|
18990
|
+
record.updatedAt.toISOString()
|
|
18991
|
+
]
|
|
18992
|
+
})
|
|
18993
|
+
);
|
|
18988
18994
|
} catch (error) {
|
|
18989
18995
|
throw new MastraError(
|
|
18990
18996
|
{
|
|
@@ -19001,26 +19007,29 @@ Note: This migration may take some time for large tables.
|
|
|
19001
19007
|
try {
|
|
19002
19008
|
const now = /* @__PURE__ */ new Date();
|
|
19003
19009
|
const observedMessageIdsJson = input.observedMessageIds ? JSON.stringify(input.observedMessageIds) : null;
|
|
19004
|
-
const result = await
|
|
19005
|
-
|
|
19006
|
-
|
|
19007
|
-
|
|
19008
|
-
|
|
19009
|
-
|
|
19010
|
-
|
|
19011
|
-
|
|
19012
|
-
|
|
19013
|
-
|
|
19014
|
-
|
|
19015
|
-
|
|
19016
|
-
|
|
19017
|
-
|
|
19018
|
-
|
|
19019
|
-
|
|
19020
|
-
|
|
19021
|
-
|
|
19022
|
-
|
|
19023
|
-
|
|
19010
|
+
const result = await withClientWriteLock(
|
|
19011
|
+
this.#client,
|
|
19012
|
+
() => this.#client.execute({
|
|
19013
|
+
sql: `UPDATE "${OM_TABLE}" SET
|
|
19014
|
+
"activeObservations" = ?,
|
|
19015
|
+
"lastObservedAt" = ?,
|
|
19016
|
+
"pendingMessageTokens" = 0,
|
|
19017
|
+
"observationTokenCount" = ?,
|
|
19018
|
+
"totalTokensObserved" = "totalTokensObserved" + ?,
|
|
19019
|
+
"observedMessageIds" = ?,
|
|
19020
|
+
"updatedAt" = ?
|
|
19021
|
+
WHERE id = ?`,
|
|
19022
|
+
args: [
|
|
19023
|
+
input.observations,
|
|
19024
|
+
input.lastObservedAt.toISOString(),
|
|
19025
|
+
input.tokenCount,
|
|
19026
|
+
input.tokenCount,
|
|
19027
|
+
observedMessageIdsJson,
|
|
19028
|
+
now.toISOString(),
|
|
19029
|
+
input.id
|
|
19030
|
+
]
|
|
19031
|
+
})
|
|
19032
|
+
);
|
|
19024
19033
|
if (result.rowsAffected === 0) {
|
|
19025
19034
|
throw new MastraError({
|
|
19026
19035
|
id: createStorageErrorId("LIBSQL", "UPDATE_ACTIVE_OBSERVATIONS", "NOT_FOUND"),
|
|
@@ -19047,78 +19056,21 @@ Note: This migration may take some time for large tables.
|
|
|
19047
19056
|
}
|
|
19048
19057
|
async createReflectionGeneration(input) {
|
|
19049
19058
|
try {
|
|
19050
|
-
|
|
19051
|
-
|
|
19052
|
-
|
|
19053
|
-
|
|
19054
|
-
|
|
19055
|
-
|
|
19056
|
-
|
|
19057
|
-
|
|
19058
|
-
|
|
19059
|
-
|
|
19060
|
-
lastObservedAt: input.currentRecord.lastObservedAt,
|
|
19061
|
-
originType: "reflection",
|
|
19062
|
-
generationCount: input.currentRecord.generationCount + 1,
|
|
19063
|
-
activeObservations: input.reflection,
|
|
19064
|
-
totalTokensObserved: input.currentRecord.totalTokensObserved,
|
|
19065
|
-
observationTokenCount: input.tokenCount,
|
|
19066
|
-
pendingMessageTokens: 0,
|
|
19067
|
-
isReflecting: false,
|
|
19068
|
-
isObserving: false,
|
|
19069
|
-
isBufferingObservation: false,
|
|
19070
|
-
isBufferingReflection: false,
|
|
19071
|
-
lastBufferedAtTokens: 0,
|
|
19072
|
-
lastBufferedAtTime: null,
|
|
19073
|
-
config: input.currentRecord.config,
|
|
19074
|
-
metadata: input.currentRecord.metadata,
|
|
19075
|
-
observedTimezone: input.currentRecord.observedTimezone
|
|
19076
|
-
};
|
|
19077
|
-
await this.#client.execute({
|
|
19078
|
-
sql: `INSERT INTO "${OM_TABLE}" (
|
|
19079
|
-
id, "lookupKey", scope, "resourceId", "threadId",
|
|
19080
|
-
"activeObservations", "activeObservationsPendingUpdate",
|
|
19081
|
-
"originType", config, "generationCount", "lastObservedAt", "lastReflectionAt",
|
|
19082
|
-
"pendingMessageTokens", "totalTokensObserved", "observationTokenCount",
|
|
19083
|
-
"isObserving", "isReflecting", "isBufferingObservation", "isBufferingReflection", "lastBufferedAtTokens", "lastBufferedAtTime",
|
|
19084
|
-
"observedTimezone", metadata, "createdAt", "updatedAt"
|
|
19085
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
19086
|
-
args: [
|
|
19087
|
-
id,
|
|
19088
|
-
lookupKey,
|
|
19089
|
-
record.scope,
|
|
19090
|
-
record.resourceId,
|
|
19091
|
-
record.threadId || null,
|
|
19092
|
-
input.reflection,
|
|
19093
|
-
null,
|
|
19094
|
-
"reflection",
|
|
19095
|
-
JSON.stringify(record.config),
|
|
19096
|
-
input.currentRecord.generationCount + 1,
|
|
19097
|
-
record.lastObservedAt?.toISOString() || null,
|
|
19098
|
-
now.toISOString(),
|
|
19099
|
-
record.pendingMessageTokens,
|
|
19100
|
-
record.totalTokensObserved,
|
|
19101
|
-
record.observationTokenCount,
|
|
19102
|
-
false,
|
|
19103
|
-
// isObserving
|
|
19104
|
-
false,
|
|
19105
|
-
// isReflecting
|
|
19106
|
-
false,
|
|
19107
|
-
// isBufferingObservation
|
|
19108
|
-
false,
|
|
19109
|
-
// isBufferingReflection
|
|
19110
|
-
0,
|
|
19111
|
-
// lastBufferedAtTokens
|
|
19112
|
-
null,
|
|
19113
|
-
// lastBufferedAtTime
|
|
19114
|
-
record.observedTimezone || null,
|
|
19115
|
-
record.metadata ? JSON.stringify(record.metadata) : null,
|
|
19116
|
-
now.toISOString(),
|
|
19117
|
-
now.toISOString()
|
|
19118
|
-
]
|
|
19059
|
+
return await withClientWriteLock(this.#client, async () => {
|
|
19060
|
+
const tx = await this.#client.transaction("write");
|
|
19061
|
+
try {
|
|
19062
|
+
const record = await this.#insertReflectionGeneration(tx, input);
|
|
19063
|
+
await tx.commit();
|
|
19064
|
+
return record;
|
|
19065
|
+
} catch (error) {
|
|
19066
|
+
if (!tx.closed) await tx.rollback();
|
|
19067
|
+
throw error;
|
|
19068
|
+
}
|
|
19119
19069
|
});
|
|
19120
|
-
return record;
|
|
19121
19070
|
} catch (error) {
|
|
19071
|
+
if (error instanceof MastraError) {
|
|
19072
|
+
throw error;
|
|
19073
|
+
}
|
|
19122
19074
|
throw new MastraError(
|
|
19123
19075
|
{
|
|
19124
19076
|
id: createStorageErrorId("LIBSQL", "CREATE_REFLECTION_GENERATION", "FAILED"),
|
|
@@ -19130,12 +19082,94 @@ Note: This migration may take some time for large tables.
|
|
|
19130
19082
|
);
|
|
19131
19083
|
}
|
|
19132
19084
|
}
|
|
19085
|
+
/**
|
|
19086
|
+
* Inserts a new reflection-generation row. Called inside a locked write
|
|
19087
|
+
* transaction — either from {@link createReflectionGeneration} (standalone)
|
|
19088
|
+
* or from {@link swapBufferedReflectionToActive} (as part of a compound
|
|
19089
|
+
* swap). Must not acquire the write lock itself; the caller owns it.
|
|
19090
|
+
*/
|
|
19091
|
+
async #insertReflectionGeneration(tx, input) {
|
|
19092
|
+
const id = crypto.randomUUID();
|
|
19093
|
+
const now = /* @__PURE__ */ new Date();
|
|
19094
|
+
const lookupKey = this.getOMKey(input.currentRecord.threadId, input.currentRecord.resourceId);
|
|
19095
|
+
const record = {
|
|
19096
|
+
id,
|
|
19097
|
+
scope: input.currentRecord.scope,
|
|
19098
|
+
threadId: input.currentRecord.threadId,
|
|
19099
|
+
resourceId: input.currentRecord.resourceId,
|
|
19100
|
+
createdAt: now,
|
|
19101
|
+
updatedAt: now,
|
|
19102
|
+
lastObservedAt: input.currentRecord.lastObservedAt,
|
|
19103
|
+
originType: "reflection",
|
|
19104
|
+
generationCount: input.currentRecord.generationCount + 1,
|
|
19105
|
+
activeObservations: input.reflection,
|
|
19106
|
+
totalTokensObserved: input.currentRecord.totalTokensObserved,
|
|
19107
|
+
observationTokenCount: input.tokenCount,
|
|
19108
|
+
pendingMessageTokens: 0,
|
|
19109
|
+
isReflecting: false,
|
|
19110
|
+
isObserving: false,
|
|
19111
|
+
isBufferingObservation: false,
|
|
19112
|
+
isBufferingReflection: false,
|
|
19113
|
+
lastBufferedAtTokens: 0,
|
|
19114
|
+
lastBufferedAtTime: null,
|
|
19115
|
+
config: input.currentRecord.config,
|
|
19116
|
+
metadata: input.currentRecord.metadata,
|
|
19117
|
+
observedTimezone: input.currentRecord.observedTimezone
|
|
19118
|
+
};
|
|
19119
|
+
await tx.execute({
|
|
19120
|
+
sql: `INSERT INTO "${OM_TABLE}" (
|
|
19121
|
+
id, "lookupKey", scope, "resourceId", "threadId",
|
|
19122
|
+
"activeObservations", "activeObservationsPendingUpdate",
|
|
19123
|
+
"originType", config, "generationCount", "lastObservedAt", "lastReflectionAt",
|
|
19124
|
+
"pendingMessageTokens", "totalTokensObserved", "observationTokenCount",
|
|
19125
|
+
"isObserving", "isReflecting", "isBufferingObservation", "isBufferingReflection", "lastBufferedAtTokens", "lastBufferedAtTime",
|
|
19126
|
+
"observedTimezone", metadata, "createdAt", "updatedAt"
|
|
19127
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
19128
|
+
args: [
|
|
19129
|
+
id,
|
|
19130
|
+
lookupKey,
|
|
19131
|
+
record.scope,
|
|
19132
|
+
record.resourceId,
|
|
19133
|
+
record.threadId || null,
|
|
19134
|
+
input.reflection,
|
|
19135
|
+
null,
|
|
19136
|
+
"reflection",
|
|
19137
|
+
JSON.stringify(record.config),
|
|
19138
|
+
input.currentRecord.generationCount + 1,
|
|
19139
|
+
record.lastObservedAt?.toISOString() || null,
|
|
19140
|
+
now.toISOString(),
|
|
19141
|
+
record.pendingMessageTokens,
|
|
19142
|
+
record.totalTokensObserved,
|
|
19143
|
+
record.observationTokenCount,
|
|
19144
|
+
false,
|
|
19145
|
+
// isObserving
|
|
19146
|
+
false,
|
|
19147
|
+
// isReflecting
|
|
19148
|
+
false,
|
|
19149
|
+
// isBufferingObservation
|
|
19150
|
+
false,
|
|
19151
|
+
// isBufferingReflection
|
|
19152
|
+
0,
|
|
19153
|
+
// lastBufferedAtTokens
|
|
19154
|
+
null,
|
|
19155
|
+
// lastBufferedAtTime
|
|
19156
|
+
record.observedTimezone || null,
|
|
19157
|
+
record.metadata ? JSON.stringify(record.metadata) : null,
|
|
19158
|
+
now.toISOString(),
|
|
19159
|
+
now.toISOString()
|
|
19160
|
+
]
|
|
19161
|
+
});
|
|
19162
|
+
return record;
|
|
19163
|
+
}
|
|
19133
19164
|
async setReflectingFlag(id, isReflecting) {
|
|
19134
19165
|
try {
|
|
19135
|
-
const result = await
|
|
19136
|
-
|
|
19137
|
-
|
|
19138
|
-
|
|
19166
|
+
const result = await withClientWriteLock(
|
|
19167
|
+
this.#client,
|
|
19168
|
+
() => this.#client.execute({
|
|
19169
|
+
sql: `UPDATE "${OM_TABLE}" SET "isReflecting" = ?, "updatedAt" = ? WHERE id = ?`,
|
|
19170
|
+
args: [isReflecting, (/* @__PURE__ */ new Date()).toISOString(), id]
|
|
19171
|
+
})
|
|
19172
|
+
);
|
|
19139
19173
|
if (result.rowsAffected === 0) {
|
|
19140
19174
|
throw new MastraError({
|
|
19141
19175
|
id: createStorageErrorId("LIBSQL", "SET_REFLECTING_FLAG", "NOT_FOUND"),
|
|
@@ -19162,10 +19196,13 @@ Note: This migration may take some time for large tables.
|
|
|
19162
19196
|
}
|
|
19163
19197
|
async setObservingFlag(id, isObserving) {
|
|
19164
19198
|
try {
|
|
19165
|
-
const result = await
|
|
19166
|
-
|
|
19167
|
-
|
|
19168
|
-
|
|
19199
|
+
const result = await withClientWriteLock(
|
|
19200
|
+
this.#client,
|
|
19201
|
+
() => this.#client.execute({
|
|
19202
|
+
sql: `UPDATE "${OM_TABLE}" SET "isObserving" = ?, "updatedAt" = ? WHERE id = ?`,
|
|
19203
|
+
args: [isObserving, (/* @__PURE__ */ new Date()).toISOString(), id]
|
|
19204
|
+
})
|
|
19205
|
+
);
|
|
19169
19206
|
if (result.rowsAffected === 0) {
|
|
19170
19207
|
throw new MastraError({
|
|
19171
19208
|
id: createStorageErrorId("LIBSQL", "SET_OBSERVING_FLAG", "NOT_FOUND"),
|
|
@@ -19202,7 +19239,7 @@ Note: This migration may take some time for large tables.
|
|
|
19202
19239
|
sql = `UPDATE "${OM_TABLE}" SET "isBufferingObservation" = ?, "updatedAt" = ? WHERE id = ?`;
|
|
19203
19240
|
args = [isBuffering, nowStr, id];
|
|
19204
19241
|
}
|
|
19205
|
-
const result = await this.#client.execute({ sql, args });
|
|
19242
|
+
const result = await withClientWriteLock(this.#client, () => this.#client.execute({ sql, args }));
|
|
19206
19243
|
if (result.rowsAffected === 0) {
|
|
19207
19244
|
throw new MastraError({
|
|
19208
19245
|
id: createStorageErrorId("LIBSQL", "SET_BUFFERING_OBSERVATION_FLAG", "NOT_FOUND"),
|
|
@@ -19229,10 +19266,13 @@ Note: This migration may take some time for large tables.
|
|
|
19229
19266
|
}
|
|
19230
19267
|
async setBufferingReflectionFlag(id, isBuffering) {
|
|
19231
19268
|
try {
|
|
19232
|
-
const result = await
|
|
19233
|
-
|
|
19234
|
-
|
|
19235
|
-
|
|
19269
|
+
const result = await withClientWriteLock(
|
|
19270
|
+
this.#client,
|
|
19271
|
+
() => this.#client.execute({
|
|
19272
|
+
sql: `UPDATE "${OM_TABLE}" SET "isBufferingReflection" = ?, "updatedAt" = ? WHERE id = ?`,
|
|
19273
|
+
args: [isBuffering, (/* @__PURE__ */ new Date()).toISOString(), id]
|
|
19274
|
+
})
|
|
19275
|
+
);
|
|
19236
19276
|
if (result.rowsAffected === 0) {
|
|
19237
19277
|
throw new MastraError({
|
|
19238
19278
|
id: createStorageErrorId("LIBSQL", "SET_BUFFERING_REFLECTION_FLAG", "NOT_FOUND"),
|
|
@@ -19260,10 +19300,13 @@ Note: This migration may take some time for large tables.
|
|
|
19260
19300
|
async clearObservationalMemory(threadId, resourceId) {
|
|
19261
19301
|
try {
|
|
19262
19302
|
const lookupKey = this.getOMKey(threadId, resourceId);
|
|
19263
|
-
await
|
|
19264
|
-
|
|
19265
|
-
|
|
19266
|
-
|
|
19303
|
+
await withClientWriteLock(
|
|
19304
|
+
this.#client,
|
|
19305
|
+
() => this.#client.execute({
|
|
19306
|
+
sql: `DELETE FROM "${OM_TABLE}" WHERE "lookupKey" = ?`,
|
|
19307
|
+
args: [lookupKey]
|
|
19308
|
+
})
|
|
19309
|
+
);
|
|
19267
19310
|
} catch (error) {
|
|
19268
19311
|
throw new MastraError(
|
|
19269
19312
|
{
|
|
@@ -19278,13 +19321,16 @@ Note: This migration may take some time for large tables.
|
|
|
19278
19321
|
}
|
|
19279
19322
|
async setPendingMessageTokens(id, tokenCount) {
|
|
19280
19323
|
try {
|
|
19281
|
-
const result = await
|
|
19282
|
-
|
|
19283
|
-
|
|
19284
|
-
|
|
19285
|
-
|
|
19286
|
-
|
|
19287
|
-
|
|
19324
|
+
const result = await withClientWriteLock(
|
|
19325
|
+
this.#client,
|
|
19326
|
+
() => this.#client.execute({
|
|
19327
|
+
sql: `UPDATE "${OM_TABLE}" SET
|
|
19328
|
+
"pendingMessageTokens" = ?,
|
|
19329
|
+
"updatedAt" = ?
|
|
19330
|
+
WHERE id = ?`,
|
|
19331
|
+
args: [tokenCount, (/* @__PURE__ */ new Date()).toISOString(), id]
|
|
19332
|
+
})
|
|
19333
|
+
);
|
|
19288
19334
|
if (result.rowsAffected === 0) {
|
|
19289
19335
|
throw new MastraError({
|
|
19290
19336
|
id: createStorageErrorId("LIBSQL", "SET_PENDING_MESSAGE_TOKENS", "NOT_FOUND"),
|
|
@@ -19311,25 +19357,34 @@ Note: This migration may take some time for large tables.
|
|
|
19311
19357
|
}
|
|
19312
19358
|
async updateObservationalMemoryConfig(input) {
|
|
19313
19359
|
try {
|
|
19314
|
-
|
|
19315
|
-
|
|
19316
|
-
|
|
19317
|
-
|
|
19318
|
-
|
|
19319
|
-
|
|
19320
|
-
|
|
19321
|
-
|
|
19322
|
-
|
|
19323
|
-
|
|
19324
|
-
|
|
19325
|
-
|
|
19326
|
-
|
|
19327
|
-
|
|
19328
|
-
|
|
19329
|
-
|
|
19330
|
-
|
|
19331
|
-
|
|
19332
|
-
|
|
19360
|
+
await withClientWriteLock(this.#client, async () => {
|
|
19361
|
+
const tx = await this.#client.transaction("write");
|
|
19362
|
+
try {
|
|
19363
|
+
const selectResult = await tx.execute({
|
|
19364
|
+
sql: `SELECT config FROM "${OM_TABLE}" WHERE id = ?`,
|
|
19365
|
+
args: [input.id]
|
|
19366
|
+
});
|
|
19367
|
+
if (selectResult.rows.length === 0) {
|
|
19368
|
+
throw new MastraError({
|
|
19369
|
+
id: createStorageErrorId("LIBSQL", "UPDATE_OM_CONFIG", "NOT_FOUND"),
|
|
19370
|
+
text: `Observational memory record not found: ${input.id}`,
|
|
19371
|
+
domain: ErrorDomain.STORAGE,
|
|
19372
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
19373
|
+
details: { id: input.id }
|
|
19374
|
+
});
|
|
19375
|
+
}
|
|
19376
|
+
const row = selectResult.rows[0];
|
|
19377
|
+
const existing = row.config ? JSON.parse(row.config) : {};
|
|
19378
|
+
const merged = this.deepMergeConfig(existing, input.config);
|
|
19379
|
+
await tx.execute({
|
|
19380
|
+
sql: `UPDATE "${OM_TABLE}" SET config = ?, "updatedAt" = ? WHERE id = ?`,
|
|
19381
|
+
args: [JSON.stringify(merged), (/* @__PURE__ */ new Date()).toISOString(), input.id]
|
|
19382
|
+
});
|
|
19383
|
+
await tx.commit();
|
|
19384
|
+
} catch (error) {
|
|
19385
|
+
if (!tx.closed) await tx.rollback();
|
|
19386
|
+
throw error;
|
|
19387
|
+
}
|
|
19333
19388
|
});
|
|
19334
19389
|
} catch (error) {
|
|
19335
19390
|
if (error instanceof MastraError) {
|
|
@@ -19352,63 +19407,72 @@ Note: This migration may take some time for large tables.
|
|
|
19352
19407
|
async updateBufferedObservations(input) {
|
|
19353
19408
|
try {
|
|
19354
19409
|
const nowStr = (/* @__PURE__ */ new Date()).toISOString();
|
|
19355
|
-
|
|
19356
|
-
|
|
19357
|
-
args: [input.id]
|
|
19358
|
-
});
|
|
19359
|
-
if (!current.rows || current.rows.length === 0) {
|
|
19360
|
-
throw new MastraError({
|
|
19361
|
-
id: createStorageErrorId("LIBSQL", "UPDATE_BUFFERED_OBSERVATIONS", "NOT_FOUND"),
|
|
19362
|
-
text: `Observational memory record not found: ${input.id}`,
|
|
19363
|
-
domain: ErrorDomain.STORAGE,
|
|
19364
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
19365
|
-
details: { id: input.id }
|
|
19366
|
-
});
|
|
19367
|
-
}
|
|
19368
|
-
const row = current.rows[0];
|
|
19369
|
-
let existingChunks = [];
|
|
19370
|
-
if (row.bufferedObservationChunks) {
|
|
19410
|
+
await withClientWriteLock(this.#client, async () => {
|
|
19411
|
+
const tx = await this.#client.transaction("write");
|
|
19371
19412
|
try {
|
|
19372
|
-
const
|
|
19373
|
-
|
|
19374
|
-
|
|
19375
|
-
|
|
19413
|
+
const current = await tx.execute({
|
|
19414
|
+
sql: `SELECT "bufferedObservationChunks" FROM "${OM_TABLE}" WHERE id = ?`,
|
|
19415
|
+
args: [input.id]
|
|
19416
|
+
});
|
|
19417
|
+
if (!current.rows || current.rows.length === 0) {
|
|
19418
|
+
throw new MastraError({
|
|
19419
|
+
id: createStorageErrorId("LIBSQL", "UPDATE_BUFFERED_OBSERVATIONS", "NOT_FOUND"),
|
|
19420
|
+
text: `Observational memory record not found: ${input.id}`,
|
|
19421
|
+
domain: ErrorDomain.STORAGE,
|
|
19422
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
19423
|
+
details: { id: input.id }
|
|
19424
|
+
});
|
|
19425
|
+
}
|
|
19426
|
+
const row = current.rows[0];
|
|
19427
|
+
let existingChunks = [];
|
|
19428
|
+
if (row.bufferedObservationChunks) {
|
|
19429
|
+
try {
|
|
19430
|
+
const parsed = typeof row.bufferedObservationChunks === "string" ? JSON.parse(row.bufferedObservationChunks) : row.bufferedObservationChunks;
|
|
19431
|
+
existingChunks = Array.isArray(parsed) ? parsed : [];
|
|
19432
|
+
} catch {
|
|
19433
|
+
existingChunks = [];
|
|
19434
|
+
}
|
|
19435
|
+
}
|
|
19436
|
+
const newChunk = {
|
|
19437
|
+
id: `ombuf-${randomUUID5()}`,
|
|
19438
|
+
cycleId: input.chunk.cycleId,
|
|
19439
|
+
observations: input.chunk.observations,
|
|
19440
|
+
tokenCount: input.chunk.tokenCount,
|
|
19441
|
+
messageIds: input.chunk.messageIds,
|
|
19442
|
+
messageTokens: input.chunk.messageTokens,
|
|
19443
|
+
lastObservedAt: input.chunk.lastObservedAt,
|
|
19444
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
19445
|
+
suggestedContinuation: input.chunk.suggestedContinuation,
|
|
19446
|
+
currentTask: input.chunk.currentTask,
|
|
19447
|
+
threadTitle: input.chunk.threadTitle,
|
|
19448
|
+
extractedValues: input.chunk.extractedValues,
|
|
19449
|
+
extractionFailures: input.chunk.extractionFailures
|
|
19450
|
+
};
|
|
19451
|
+
const newChunks = [...existingChunks, newChunk];
|
|
19452
|
+
const lastBufferedAtTime = input.lastBufferedAtTime ? input.lastBufferedAtTime.toISOString() : null;
|
|
19453
|
+
const result = await tx.execute({
|
|
19454
|
+
sql: `UPDATE "${OM_TABLE}" SET
|
|
19455
|
+
"bufferedObservationChunks" = ?,
|
|
19456
|
+
"lastBufferedAtTime" = COALESCE(?, "lastBufferedAtTime"),
|
|
19457
|
+
"updatedAt" = ?
|
|
19458
|
+
WHERE id = ?`,
|
|
19459
|
+
args: [JSON.stringify(newChunks), lastBufferedAtTime, nowStr, input.id]
|
|
19460
|
+
});
|
|
19461
|
+
if (result.rowsAffected === 0) {
|
|
19462
|
+
throw new MastraError({
|
|
19463
|
+
id: createStorageErrorId("LIBSQL", "UPDATE_BUFFERED_OBSERVATIONS", "NOT_FOUND"),
|
|
19464
|
+
text: `Observational memory record not found: ${input.id}`,
|
|
19465
|
+
domain: ErrorDomain.STORAGE,
|
|
19466
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
19467
|
+
details: { id: input.id }
|
|
19468
|
+
});
|
|
19469
|
+
}
|
|
19470
|
+
await tx.commit();
|
|
19471
|
+
} catch (error) {
|
|
19472
|
+
if (!tx.closed) await tx.rollback();
|
|
19473
|
+
throw error;
|
|
19376
19474
|
}
|
|
19377
|
-
}
|
|
19378
|
-
const newChunk = {
|
|
19379
|
-
id: `ombuf-${randomUUID5()}`,
|
|
19380
|
-
cycleId: input.chunk.cycleId,
|
|
19381
|
-
observations: input.chunk.observations,
|
|
19382
|
-
tokenCount: input.chunk.tokenCount,
|
|
19383
|
-
messageIds: input.chunk.messageIds,
|
|
19384
|
-
messageTokens: input.chunk.messageTokens,
|
|
19385
|
-
lastObservedAt: input.chunk.lastObservedAt,
|
|
19386
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
19387
|
-
suggestedContinuation: input.chunk.suggestedContinuation,
|
|
19388
|
-
currentTask: input.chunk.currentTask,
|
|
19389
|
-
threadTitle: input.chunk.threadTitle,
|
|
19390
|
-
extractedValues: input.chunk.extractedValues,
|
|
19391
|
-
extractionFailures: input.chunk.extractionFailures
|
|
19392
|
-
};
|
|
19393
|
-
const newChunks = [...existingChunks, newChunk];
|
|
19394
|
-
const lastBufferedAtTime = input.lastBufferedAtTime ? input.lastBufferedAtTime.toISOString() : null;
|
|
19395
|
-
const result = await this.#client.execute({
|
|
19396
|
-
sql: `UPDATE "${OM_TABLE}" SET
|
|
19397
|
-
"bufferedObservationChunks" = ?,
|
|
19398
|
-
"lastBufferedAtTime" = COALESCE(?, "lastBufferedAtTime"),
|
|
19399
|
-
"updatedAt" = ?
|
|
19400
|
-
WHERE id = ?`,
|
|
19401
|
-
args: [JSON.stringify(newChunks), lastBufferedAtTime, nowStr, input.id]
|
|
19402
19475
|
});
|
|
19403
|
-
if (result.rowsAffected === 0) {
|
|
19404
|
-
throw new MastraError({
|
|
19405
|
-
id: createStorageErrorId("LIBSQL", "UPDATE_BUFFERED_OBSERVATIONS", "NOT_FOUND"),
|
|
19406
|
-
text: `Observational memory record not found: ${input.id}`,
|
|
19407
|
-
domain: ErrorDomain.STORAGE,
|
|
19408
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
19409
|
-
details: { id: input.id }
|
|
19410
|
-
});
|
|
19411
|
-
}
|
|
19412
19476
|
} catch (error) {
|
|
19413
19477
|
if (error instanceof MastraError) {
|
|
19414
19478
|
throw error;
|
|
@@ -19427,150 +19491,160 @@ Note: This migration may take some time for large tables.
|
|
|
19427
19491
|
async swapBufferedToActive(input) {
|
|
19428
19492
|
try {
|
|
19429
19493
|
const nowStr = (/* @__PURE__ */ new Date()).toISOString();
|
|
19430
|
-
|
|
19431
|
-
|
|
19432
|
-
args: [input.id]
|
|
19433
|
-
});
|
|
19434
|
-
if (!current.rows || current.rows.length === 0) {
|
|
19435
|
-
throw new MastraError({
|
|
19436
|
-
id: createStorageErrorId("LIBSQL", "SWAP_BUFFERED_TO_ACTIVE", "NOT_FOUND"),
|
|
19437
|
-
text: `Observational memory record not found: ${input.id}`,
|
|
19438
|
-
domain: ErrorDomain.STORAGE,
|
|
19439
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
19440
|
-
details: { id: input.id }
|
|
19441
|
-
});
|
|
19442
|
-
}
|
|
19443
|
-
const row = current.rows[0];
|
|
19444
|
-
let chunks = [];
|
|
19445
|
-
if (row.bufferedObservationChunks) {
|
|
19494
|
+
return await withClientWriteLock(this.#client, async () => {
|
|
19495
|
+
const tx = await this.#client.transaction("write");
|
|
19446
19496
|
try {
|
|
19447
|
-
const
|
|
19448
|
-
|
|
19449
|
-
|
|
19450
|
-
|
|
19451
|
-
|
|
19452
|
-
|
|
19453
|
-
|
|
19454
|
-
|
|
19455
|
-
|
|
19456
|
-
|
|
19457
|
-
|
|
19458
|
-
|
|
19459
|
-
activatedCycleIds: [],
|
|
19460
|
-
activatedMessageIds: []
|
|
19461
|
-
};
|
|
19462
|
-
}
|
|
19463
|
-
const retentionFloor = input.messageTokensThreshold * (1 - input.activationRatio);
|
|
19464
|
-
const targetMessageTokens = Math.max(0, input.currentPendingTokens - retentionFloor);
|
|
19465
|
-
let cumulativeMessageTokens = 0;
|
|
19466
|
-
let bestOverBoundary = 0;
|
|
19467
|
-
let bestOverTokens = 0;
|
|
19468
|
-
let bestUnderBoundary = 0;
|
|
19469
|
-
let bestUnderTokens = 0;
|
|
19470
|
-
for (let i = 0; i < chunks.length; i++) {
|
|
19471
|
-
cumulativeMessageTokens += chunks[i].messageTokens ?? 0;
|
|
19472
|
-
const boundary2 = i + 1;
|
|
19473
|
-
if (cumulativeMessageTokens >= targetMessageTokens) {
|
|
19474
|
-
if (bestOverBoundary === 0 || cumulativeMessageTokens < bestOverTokens) {
|
|
19475
|
-
bestOverBoundary = boundary2;
|
|
19476
|
-
bestOverTokens = cumulativeMessageTokens;
|
|
19497
|
+
const current = await tx.execute({
|
|
19498
|
+
sql: `SELECT * FROM "${OM_TABLE}" WHERE id = ?`,
|
|
19499
|
+
args: [input.id]
|
|
19500
|
+
});
|
|
19501
|
+
if (!current.rows || current.rows.length === 0) {
|
|
19502
|
+
throw new MastraError({
|
|
19503
|
+
id: createStorageErrorId("LIBSQL", "SWAP_BUFFERED_TO_ACTIVE", "NOT_FOUND"),
|
|
19504
|
+
text: `Observational memory record not found: ${input.id}`,
|
|
19505
|
+
domain: ErrorDomain.STORAGE,
|
|
19506
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
19507
|
+
details: { id: input.id }
|
|
19508
|
+
});
|
|
19477
19509
|
}
|
|
19478
|
-
|
|
19479
|
-
|
|
19480
|
-
|
|
19481
|
-
|
|
19510
|
+
const row = current.rows[0];
|
|
19511
|
+
let chunks = [];
|
|
19512
|
+
if (row.bufferedObservationChunks) {
|
|
19513
|
+
try {
|
|
19514
|
+
const parsed = typeof row.bufferedObservationChunks === "string" ? JSON.parse(row.bufferedObservationChunks) : row.bufferedObservationChunks;
|
|
19515
|
+
chunks = Array.isArray(parsed) ? parsed : [];
|
|
19516
|
+
} catch {
|
|
19517
|
+
chunks = [];
|
|
19518
|
+
}
|
|
19482
19519
|
}
|
|
19483
|
-
|
|
19484
|
-
|
|
19485
|
-
|
|
19486
|
-
|
|
19487
|
-
|
|
19488
|
-
|
|
19489
|
-
|
|
19490
|
-
|
|
19491
|
-
|
|
19492
|
-
|
|
19493
|
-
|
|
19494
|
-
|
|
19495
|
-
|
|
19496
|
-
|
|
19497
|
-
|
|
19498
|
-
|
|
19499
|
-
|
|
19500
|
-
|
|
19501
|
-
|
|
19502
|
-
|
|
19503
|
-
|
|
19504
|
-
|
|
19505
|
-
|
|
19506
|
-
|
|
19507
|
-
|
|
19508
|
-
|
|
19509
|
-
|
|
19510
|
-
|
|
19511
|
-
|
|
19512
|
-
|
|
19513
|
-
|
|
19514
|
-
|
|
19515
|
-
|
|
19520
|
+
if (chunks.length === 0) {
|
|
19521
|
+
await tx.commit();
|
|
19522
|
+
return {
|
|
19523
|
+
chunksActivated: 0,
|
|
19524
|
+
messageTokensActivated: 0,
|
|
19525
|
+
observationTokensActivated: 0,
|
|
19526
|
+
messagesActivated: 0,
|
|
19527
|
+
activatedCycleIds: [],
|
|
19528
|
+
activatedMessageIds: []
|
|
19529
|
+
};
|
|
19530
|
+
}
|
|
19531
|
+
const retentionFloor = input.messageTokensThreshold * (1 - input.activationRatio);
|
|
19532
|
+
const targetMessageTokens = Math.max(0, input.currentPendingTokens - retentionFloor);
|
|
19533
|
+
let cumulativeMessageTokens = 0;
|
|
19534
|
+
let bestOverBoundary = 0;
|
|
19535
|
+
let bestOverTokens = 0;
|
|
19536
|
+
let bestUnderBoundary = 0;
|
|
19537
|
+
let bestUnderTokens = 0;
|
|
19538
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
19539
|
+
cumulativeMessageTokens += chunks[i].messageTokens ?? 0;
|
|
19540
|
+
const boundary2 = i + 1;
|
|
19541
|
+
if (cumulativeMessageTokens >= targetMessageTokens) {
|
|
19542
|
+
if (bestOverBoundary === 0 || cumulativeMessageTokens < bestOverTokens) {
|
|
19543
|
+
bestOverBoundary = boundary2;
|
|
19544
|
+
bestOverTokens = cumulativeMessageTokens;
|
|
19545
|
+
}
|
|
19546
|
+
} else {
|
|
19547
|
+
if (cumulativeMessageTokens > bestUnderTokens) {
|
|
19548
|
+
bestUnderBoundary = boundary2;
|
|
19549
|
+
bestUnderTokens = cumulativeMessageTokens;
|
|
19550
|
+
}
|
|
19551
|
+
}
|
|
19552
|
+
}
|
|
19553
|
+
const maxOvershoot = retentionFloor * 0.95;
|
|
19554
|
+
const overshoot = bestOverTokens - targetMessageTokens;
|
|
19555
|
+
const remainingAfterOver = input.currentPendingTokens - bestOverTokens;
|
|
19556
|
+
const remainingAfterUnder = input.currentPendingTokens - bestUnderTokens;
|
|
19557
|
+
const minRemaining = Math.min(1e3, retentionFloor);
|
|
19558
|
+
let chunksToActivate;
|
|
19559
|
+
if (input.forceMaxActivation && bestOverBoundary > 0 && remainingAfterOver >= minRemaining) {
|
|
19560
|
+
chunksToActivate = bestOverBoundary;
|
|
19561
|
+
} else if (bestOverBoundary > 0 && overshoot <= maxOvershoot && remainingAfterOver >= minRemaining) {
|
|
19562
|
+
chunksToActivate = bestOverBoundary;
|
|
19563
|
+
} else if (bestUnderBoundary > 0 && remainingAfterUnder >= minRemaining) {
|
|
19564
|
+
chunksToActivate = bestUnderBoundary;
|
|
19565
|
+
} else if (bestOverBoundary > 0) {
|
|
19566
|
+
chunksToActivate = bestOverBoundary;
|
|
19567
|
+
} else {
|
|
19568
|
+
chunksToActivate = 1;
|
|
19569
|
+
}
|
|
19570
|
+
const activatedChunks = chunks.slice(0, chunksToActivate);
|
|
19571
|
+
const remainingChunks = chunks.slice(chunksToActivate);
|
|
19572
|
+
const activatedContent = activatedChunks.map((c) => c.observations).join("\n\n");
|
|
19573
|
+
const activatedTokens = activatedChunks.reduce((sum, c) => sum + c.tokenCount, 0);
|
|
19574
|
+
const activatedMessageTokens = activatedChunks.reduce((sum, c) => sum + (c.messageTokens ?? 0), 0);
|
|
19575
|
+
const activatedMessageCount = activatedChunks.reduce((sum, c) => sum + c.messageIds.length, 0);
|
|
19576
|
+
const activatedCycleIds = activatedChunks.map((c) => c.cycleId).filter((id) => !!id);
|
|
19577
|
+
const activatedMessageIds = activatedChunks.flatMap((c) => c.messageIds ?? []);
|
|
19578
|
+
const latestChunk = activatedChunks[activatedChunks.length - 1];
|
|
19579
|
+
const lastObservedAt = input.lastObservedAt ?? (latestChunk?.lastObservedAt ? new Date(latestChunk.lastObservedAt) : /* @__PURE__ */ new Date());
|
|
19580
|
+
const lastObservedAtStr = lastObservedAt.toISOString();
|
|
19581
|
+
const existingActive = row.activeObservations || "";
|
|
19582
|
+
const existingTokenCount = Number(row.observationTokenCount || 0);
|
|
19583
|
+
const boundary = `
|
|
19516
19584
|
|
|
19517
19585
|
--- message boundary (${lastObservedAt.toISOString()}) ---
|
|
19518
19586
|
|
|
19519
19587
|
`;
|
|
19520
|
-
|
|
19521
|
-
|
|
19522
|
-
|
|
19523
|
-
|
|
19524
|
-
|
|
19525
|
-
|
|
19526
|
-
|
|
19527
|
-
|
|
19528
|
-
|
|
19529
|
-
|
|
19530
|
-
|
|
19531
|
-
|
|
19532
|
-
|
|
19533
|
-
|
|
19534
|
-
|
|
19535
|
-
|
|
19536
|
-
|
|
19537
|
-
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
|
|
19541
|
-
|
|
19542
|
-
|
|
19543
|
-
|
|
19588
|
+
const newActive = existingActive ? `${existingActive}${boundary}${activatedContent}` : activatedContent;
|
|
19589
|
+
const newTokenCount = existingTokenCount + activatedTokens;
|
|
19590
|
+
const existingPending = Number(row.pendingMessageTokens || 0);
|
|
19591
|
+
const newPending = Math.max(0, existingPending - activatedMessageTokens);
|
|
19592
|
+
const updateResult = await tx.execute({
|
|
19593
|
+
sql: `UPDATE "${OM_TABLE}" SET
|
|
19594
|
+
"activeObservations" = ?,
|
|
19595
|
+
"observationTokenCount" = ?,
|
|
19596
|
+
"pendingMessageTokens" = ?,
|
|
19597
|
+
"bufferedObservationChunks" = ?,
|
|
19598
|
+
"lastObservedAt" = ?,
|
|
19599
|
+
"updatedAt" = ?
|
|
19600
|
+
WHERE id = ?
|
|
19601
|
+
AND "bufferedObservationChunks" IS NOT NULL
|
|
19602
|
+
AND "bufferedObservationChunks" != '[]'`,
|
|
19603
|
+
args: [
|
|
19604
|
+
newActive,
|
|
19605
|
+
newTokenCount,
|
|
19606
|
+
newPending,
|
|
19607
|
+
remainingChunks.length > 0 ? JSON.stringify(remainingChunks) : null,
|
|
19608
|
+
lastObservedAtStr,
|
|
19609
|
+
nowStr,
|
|
19610
|
+
input.id
|
|
19611
|
+
]
|
|
19612
|
+
});
|
|
19613
|
+
await tx.commit();
|
|
19614
|
+
if (updateResult.rowsAffected === 0) {
|
|
19615
|
+
return {
|
|
19616
|
+
chunksActivated: 0,
|
|
19617
|
+
messageTokensActivated: 0,
|
|
19618
|
+
observationTokensActivated: 0,
|
|
19619
|
+
messagesActivated: 0,
|
|
19620
|
+
activatedCycleIds: [],
|
|
19621
|
+
activatedMessageIds: []
|
|
19622
|
+
};
|
|
19623
|
+
}
|
|
19624
|
+
const latestChunkHints = activatedChunks[activatedChunks.length - 1];
|
|
19625
|
+
return {
|
|
19626
|
+
chunksActivated: activatedChunks.length,
|
|
19627
|
+
messageTokensActivated: activatedMessageTokens,
|
|
19628
|
+
observationTokensActivated: activatedTokens,
|
|
19629
|
+
messagesActivated: activatedMessageCount,
|
|
19630
|
+
activatedCycleIds,
|
|
19631
|
+
activatedMessageIds,
|
|
19632
|
+
observations: activatedContent,
|
|
19633
|
+
perChunk: activatedChunks.map((c) => ({
|
|
19634
|
+
cycleId: c.cycleId ?? "",
|
|
19635
|
+
messageTokens: c.messageTokens ?? 0,
|
|
19636
|
+
observationTokens: c.tokenCount,
|
|
19637
|
+
messageCount: c.messageIds.length,
|
|
19638
|
+
observations: c.observations
|
|
19639
|
+
})),
|
|
19640
|
+
suggestedContinuation: latestChunkHints?.suggestedContinuation ?? void 0,
|
|
19641
|
+
currentTask: latestChunkHints?.currentTask ?? void 0
|
|
19642
|
+
};
|
|
19643
|
+
} catch (error) {
|
|
19644
|
+
if (!tx.closed) await tx.rollback();
|
|
19645
|
+
throw error;
|
|
19646
|
+
}
|
|
19544
19647
|
});
|
|
19545
|
-
if (updateResult.rowsAffected === 0) {
|
|
19546
|
-
return {
|
|
19547
|
-
chunksActivated: 0,
|
|
19548
|
-
messageTokensActivated: 0,
|
|
19549
|
-
observationTokensActivated: 0,
|
|
19550
|
-
messagesActivated: 0,
|
|
19551
|
-
activatedCycleIds: [],
|
|
19552
|
-
activatedMessageIds: []
|
|
19553
|
-
};
|
|
19554
|
-
}
|
|
19555
|
-
const latestChunkHints = activatedChunks[activatedChunks.length - 1];
|
|
19556
|
-
return {
|
|
19557
|
-
chunksActivated: activatedChunks.length,
|
|
19558
|
-
messageTokensActivated: activatedMessageTokens,
|
|
19559
|
-
observationTokensActivated: activatedTokens,
|
|
19560
|
-
messagesActivated: activatedMessageCount,
|
|
19561
|
-
activatedCycleIds,
|
|
19562
|
-
activatedMessageIds,
|
|
19563
|
-
observations: activatedContent,
|
|
19564
|
-
perChunk: activatedChunks.map((c) => ({
|
|
19565
|
-
cycleId: c.cycleId ?? "",
|
|
19566
|
-
messageTokens: c.messageTokens ?? 0,
|
|
19567
|
-
observationTokens: c.tokenCount,
|
|
19568
|
-
messageCount: c.messageIds.length,
|
|
19569
|
-
observations: c.observations
|
|
19570
|
-
})),
|
|
19571
|
-
suggestedContinuation: latestChunkHints?.suggestedContinuation ?? void 0,
|
|
19572
|
-
currentTask: latestChunkHints?.currentTask ?? void 0
|
|
19573
|
-
};
|
|
19574
19648
|
} catch (error) {
|
|
19575
19649
|
if (error instanceof MastraError) {
|
|
19576
19650
|
throw error;
|
|
@@ -19589,28 +19663,31 @@ Note: This migration may take some time for large tables.
|
|
|
19589
19663
|
async updateBufferedReflection(input) {
|
|
19590
19664
|
try {
|
|
19591
19665
|
const nowStr = (/* @__PURE__ */ new Date()).toISOString();
|
|
19592
|
-
const result = await
|
|
19593
|
-
|
|
19594
|
-
|
|
19595
|
-
|
|
19596
|
-
|
|
19597
|
-
|
|
19598
|
-
|
|
19599
|
-
|
|
19600
|
-
|
|
19601
|
-
|
|
19602
|
-
|
|
19603
|
-
|
|
19604
|
-
|
|
19605
|
-
|
|
19606
|
-
|
|
19607
|
-
|
|
19608
|
-
|
|
19609
|
-
|
|
19610
|
-
|
|
19611
|
-
|
|
19612
|
-
|
|
19613
|
-
|
|
19666
|
+
const result = await withClientWriteLock(
|
|
19667
|
+
this.#client,
|
|
19668
|
+
() => this.#client.execute({
|
|
19669
|
+
sql: `UPDATE "${OM_TABLE}" SET
|
|
19670
|
+
"bufferedReflection" = CASE
|
|
19671
|
+
WHEN "bufferedReflection" IS NOT NULL AND "bufferedReflection" != ''
|
|
19672
|
+
THEN "bufferedReflection" || char(10) || char(10) || ?
|
|
19673
|
+
ELSE ?
|
|
19674
|
+
END,
|
|
19675
|
+
"bufferedReflectionTokens" = COALESCE("bufferedReflectionTokens", 0) + ?,
|
|
19676
|
+
"bufferedReflectionInputTokens" = COALESCE("bufferedReflectionInputTokens", 0) + ?,
|
|
19677
|
+
"reflectedObservationLineCount" = ?,
|
|
19678
|
+
"updatedAt" = ?
|
|
19679
|
+
WHERE id = ?`,
|
|
19680
|
+
args: [
|
|
19681
|
+
input.reflection,
|
|
19682
|
+
input.reflection,
|
|
19683
|
+
input.tokenCount,
|
|
19684
|
+
input.inputTokenCount,
|
|
19685
|
+
input.reflectedObservationLineCount,
|
|
19686
|
+
nowStr,
|
|
19687
|
+
input.id
|
|
19688
|
+
]
|
|
19689
|
+
})
|
|
19690
|
+
);
|
|
19614
19691
|
if (result.rowsAffected === 0) {
|
|
19615
19692
|
throw new MastraError({
|
|
19616
19693
|
id: createStorageErrorId("LIBSQL", "UPDATE_BUFFERED_REFLECTION", "NOT_FOUND"),
|
|
@@ -19637,55 +19714,64 @@ Note: This migration may take some time for large tables.
|
|
|
19637
19714
|
}
|
|
19638
19715
|
async swapBufferedReflectionToActive(input) {
|
|
19639
19716
|
try {
|
|
19640
|
-
|
|
19641
|
-
|
|
19642
|
-
|
|
19643
|
-
|
|
19644
|
-
|
|
19645
|
-
|
|
19646
|
-
|
|
19647
|
-
|
|
19648
|
-
|
|
19649
|
-
|
|
19650
|
-
|
|
19651
|
-
|
|
19652
|
-
|
|
19653
|
-
|
|
19654
|
-
|
|
19655
|
-
|
|
19656
|
-
|
|
19657
|
-
|
|
19658
|
-
|
|
19659
|
-
|
|
19660
|
-
|
|
19661
|
-
|
|
19662
|
-
|
|
19663
|
-
|
|
19664
|
-
|
|
19665
|
-
|
|
19666
|
-
|
|
19667
|
-
|
|
19668
|
-
|
|
19669
|
-
|
|
19717
|
+
return await withClientWriteLock(this.#client, async () => {
|
|
19718
|
+
const tx = await this.#client.transaction("write");
|
|
19719
|
+
try {
|
|
19720
|
+
const current = await tx.execute({
|
|
19721
|
+
sql: `SELECT * FROM "${OM_TABLE}" WHERE id = ?`,
|
|
19722
|
+
args: [input.currentRecord.id]
|
|
19723
|
+
});
|
|
19724
|
+
if (!current.rows || current.rows.length === 0) {
|
|
19725
|
+
throw new MastraError({
|
|
19726
|
+
id: createStorageErrorId("LIBSQL", "SWAP_BUFFERED_REFLECTION_TO_ACTIVE", "NOT_FOUND"),
|
|
19727
|
+
text: `Observational memory record not found: ${input.currentRecord.id}`,
|
|
19728
|
+
domain: ErrorDomain.STORAGE,
|
|
19729
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
19730
|
+
details: { id: input.currentRecord.id }
|
|
19731
|
+
});
|
|
19732
|
+
}
|
|
19733
|
+
const row = current.rows[0];
|
|
19734
|
+
const bufferedReflection = row.bufferedReflection || "";
|
|
19735
|
+
const reflectedLineCount = Number(row.reflectedObservationLineCount || 0);
|
|
19736
|
+
if (!bufferedReflection) {
|
|
19737
|
+
throw new MastraError({
|
|
19738
|
+
id: createStorageErrorId("LIBSQL", "SWAP_BUFFERED_REFLECTION_TO_ACTIVE", "NO_CONTENT"),
|
|
19739
|
+
text: "No buffered reflection to swap",
|
|
19740
|
+
domain: ErrorDomain.STORAGE,
|
|
19741
|
+
category: ErrorCategory.USER,
|
|
19742
|
+
details: { id: input.currentRecord.id }
|
|
19743
|
+
});
|
|
19744
|
+
}
|
|
19745
|
+
const currentObservations = row.activeObservations || "";
|
|
19746
|
+
const allLines = currentObservations.split("\n");
|
|
19747
|
+
const unreflectedLines = allLines.slice(reflectedLineCount);
|
|
19748
|
+
const unreflectedContent = unreflectedLines.join("\n").trim();
|
|
19749
|
+
const newObservations = unreflectedContent ? `${bufferedReflection}
|
|
19670
19750
|
|
|
19671
19751
|
${unreflectedContent}` : bufferedReflection;
|
|
19672
|
-
|
|
19673
|
-
|
|
19674
|
-
|
|
19675
|
-
|
|
19752
|
+
const newRecord = await this.#insertReflectionGeneration(tx, {
|
|
19753
|
+
currentRecord: input.currentRecord,
|
|
19754
|
+
reflection: newObservations,
|
|
19755
|
+
tokenCount: input.tokenCount
|
|
19756
|
+
});
|
|
19757
|
+
const nowStr = (/* @__PURE__ */ new Date()).toISOString();
|
|
19758
|
+
await tx.execute({
|
|
19759
|
+
sql: `UPDATE "${OM_TABLE}" SET
|
|
19760
|
+
"bufferedReflection" = NULL,
|
|
19761
|
+
"bufferedReflectionTokens" = NULL,
|
|
19762
|
+
"bufferedReflectionInputTokens" = NULL,
|
|
19763
|
+
"reflectedObservationLineCount" = NULL,
|
|
19764
|
+
"updatedAt" = ?
|
|
19765
|
+
WHERE id = ?`,
|
|
19766
|
+
args: [nowStr, input.currentRecord.id]
|
|
19767
|
+
});
|
|
19768
|
+
await tx.commit();
|
|
19769
|
+
return newRecord;
|
|
19770
|
+
} catch (error) {
|
|
19771
|
+
if (!tx.closed) await tx.rollback();
|
|
19772
|
+
throw error;
|
|
19773
|
+
}
|
|
19676
19774
|
});
|
|
19677
|
-
const nowStr = (/* @__PURE__ */ new Date()).toISOString();
|
|
19678
|
-
await this.#client.execute({
|
|
19679
|
-
sql: `UPDATE "${OM_TABLE}" SET
|
|
19680
|
-
"bufferedReflection" = NULL,
|
|
19681
|
-
"bufferedReflectionTokens" = NULL,
|
|
19682
|
-
"bufferedReflectionInputTokens" = NULL,
|
|
19683
|
-
"reflectedObservationLineCount" = NULL,
|
|
19684
|
-
"updatedAt" = ?
|
|
19685
|
-
WHERE id = ?`,
|
|
19686
|
-
args: [nowStr, input.currentRecord.id]
|
|
19687
|
-
});
|
|
19688
|
-
return newRecord;
|
|
19689
19775
|
} catch (error) {
|
|
19690
19776
|
if (error instanceof MastraError) {
|
|
19691
19777
|
throw error;
|
|
@@ -25423,6 +25509,34 @@ function getGithubFeatureDiagnostics(options) {
|
|
|
25423
25509
|
// src/integrations/github/project-lock.ts
|
|
25424
25510
|
import { createHash } from "crypto";
|
|
25425
25511
|
var inProcessLocks = /* @__PURE__ */ new Map();
|
|
25512
|
+
var DEFAULT_PROJECT_LOCK_TIMEOUT_MS = 6e4;
|
|
25513
|
+
var ProjectLockTimeoutError = class extends Error {
|
|
25514
|
+
key;
|
|
25515
|
+
timeoutMs;
|
|
25516
|
+
constructor(key, timeoutMs) {
|
|
25517
|
+
super(`Project lock critical section for "${key}" exceeded ${timeoutMs}ms`);
|
|
25518
|
+
this.name = "ProjectLockTimeoutError";
|
|
25519
|
+
this.key = key;
|
|
25520
|
+
this.timeoutMs = timeoutMs;
|
|
25521
|
+
}
|
|
25522
|
+
};
|
|
25523
|
+
async function runWithTimeout(key, timeoutMs, fn) {
|
|
25524
|
+
const controller = new AbortController();
|
|
25525
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
25526
|
+
const abortError = new Promise((_, reject) => {
|
|
25527
|
+
controller.signal.addEventListener("abort", () => reject(new ProjectLockTimeoutError(key, timeoutMs)), {
|
|
25528
|
+
once: true
|
|
25529
|
+
});
|
|
25530
|
+
});
|
|
25531
|
+
const work = fn(controller.signal);
|
|
25532
|
+
work.catch(() => {
|
|
25533
|
+
});
|
|
25534
|
+
try {
|
|
25535
|
+
return await Promise.race([work, abortError]);
|
|
25536
|
+
} finally {
|
|
25537
|
+
clearTimeout(timer);
|
|
25538
|
+
}
|
|
25539
|
+
}
|
|
25426
25540
|
function hashKey(key) {
|
|
25427
25541
|
const digest = createHash("sha256").update(key).digest();
|
|
25428
25542
|
const a = digest.readInt32BE(0);
|
|
@@ -25430,9 +25544,9 @@ function hashKey(key) {
|
|
|
25430
25544
|
return [a, b];
|
|
25431
25545
|
}
|
|
25432
25546
|
function withProjectLock(options) {
|
|
25433
|
-
const { key, storage, fn, pool } = options;
|
|
25547
|
+
const { key, storage, fn, pool, timeoutMs = DEFAULT_PROJECT_LOCK_TIMEOUT_MS } = options;
|
|
25434
25548
|
const prev = inProcessLocks.get(key) ?? Promise.resolve();
|
|
25435
|
-
const run = () => withDbAdvisoryLock({ key, storage, fn, pool });
|
|
25549
|
+
const run = () => withDbAdvisoryLock({ key, storage, fn, pool, timeoutMs });
|
|
25436
25550
|
const next = prev.then(run, run);
|
|
25437
25551
|
const tail = next.then(
|
|
25438
25552
|
() => void 0,
|
|
@@ -25447,28 +25561,31 @@ function withProjectLock(options) {
|
|
|
25447
25561
|
return next;
|
|
25448
25562
|
}
|
|
25449
25563
|
async function withDbAdvisoryLock(options) {
|
|
25450
|
-
const { key, storage, fn, pool } = options;
|
|
25564
|
+
const { key, storage, fn, pool, timeoutMs = DEFAULT_PROJECT_LOCK_TIMEOUT_MS } = options;
|
|
25451
25565
|
if (process.env.MASTRACODE_DISTRIBUTED_LOCK === "0") {
|
|
25452
|
-
return fn
|
|
25566
|
+
return runWithTimeout(key, timeoutMs, fn);
|
|
25453
25567
|
}
|
|
25454
|
-
if (pool) return advisoryLockOver(pool, key, fn);
|
|
25568
|
+
if (pool) return advisoryLockOver(pool, key, timeoutMs, fn);
|
|
25455
25569
|
if (typeof storage?.withDistributedLock !== "function") {
|
|
25456
|
-
return fn
|
|
25570
|
+
return runWithTimeout(key, timeoutMs, fn);
|
|
25457
25571
|
}
|
|
25458
|
-
return storage.withDistributedLock(key, fn);
|
|
25572
|
+
return storage.withDistributedLock(key, () => runWithTimeout(key, timeoutMs, fn));
|
|
25459
25573
|
}
|
|
25460
|
-
async function advisoryLockOver(pool, key, fn) {
|
|
25574
|
+
async function advisoryLockOver(pool, key, timeoutMs, fn) {
|
|
25461
25575
|
const [k1, k2] = hashKey(key);
|
|
25462
25576
|
const client = await pool.connect();
|
|
25463
25577
|
try {
|
|
25464
25578
|
await client.query("BEGIN");
|
|
25465
25579
|
await client.query("SELECT pg_advisory_xact_lock($1, $2)", [k1, k2]);
|
|
25466
25580
|
try {
|
|
25467
|
-
const result = await fn
|
|
25581
|
+
const result = await runWithTimeout(key, timeoutMs, fn);
|
|
25468
25582
|
await client.query("COMMIT");
|
|
25469
25583
|
return result;
|
|
25470
25584
|
} catch (err) {
|
|
25471
|
-
|
|
25585
|
+
try {
|
|
25586
|
+
await client.query("ROLLBACK");
|
|
25587
|
+
} catch {
|
|
25588
|
+
}
|
|
25472
25589
|
throw err;
|
|
25473
25590
|
}
|
|
25474
25591
|
} finally {
|
|
@@ -26444,7 +26561,7 @@ function buildGithubRoutes(options) {
|
|
|
26444
26561
|
list = await github.listInstallationRepos(Number(inst.externalId));
|
|
26445
26562
|
} catch (err) {
|
|
26446
26563
|
if (err.status !== 404) throw err;
|
|
26447
|
-
console.error(`[
|
|
26564
|
+
console.error(`[Mastra Factory] pruning stale GitHub installation ${inst.externalId} (404 from GitHub)`);
|
|
26448
26565
|
await github.sourceControlStorage.installations.delete({ orgId: resolved.tenant.orgId, id: inst.id });
|
|
26449
26566
|
continue;
|
|
26450
26567
|
}
|
|
@@ -27387,7 +27504,7 @@ function logPlatformError(message, fields) {
|
|
|
27387
27504
|
}
|
|
27388
27505
|
function writePlatformLog(level, message, fields) {
|
|
27389
27506
|
const metadata = fields ? ` ${JSON.stringify(stripUndefined(fields))}` : "";
|
|
27390
|
-
process.stderr.write(`[
|
|
27507
|
+
process.stderr.write(`[Mastra Factory] ${level.toUpperCase()} ${message}${metadata}
|
|
27391
27508
|
`);
|
|
27392
27509
|
}
|
|
27393
27510
|
function stripUndefined(fields) {
|
|
@@ -27404,7 +27521,7 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
27404
27521
|
import { isLeaseProvider, NoopLeaseProvider } from "@mastra/core/events";
|
|
27405
27522
|
import { MastraWorker } from "@mastra/core/worker";
|
|
27406
27523
|
var API_PREFIX = "/v1/server/github-app";
|
|
27407
|
-
var DEFAULT_POLL_INTERVAL_MS =
|
|
27524
|
+
var DEFAULT_POLL_INTERVAL_MS = 2e4;
|
|
27408
27525
|
var EVENT_PAGE_SIZE = 500;
|
|
27409
27526
|
var MIN_LEASE_TTL_MS = 3e4;
|
|
27410
27527
|
var CURSOR_ORG_ID = "__platform_github_event_worker__";
|
|
@@ -27594,10 +27711,16 @@ var PlatformGithubEventWorker = class extends MastraWorker {
|
|
|
27594
27711
|
const query = new URLSearchParams({ limit: String(EVENT_PAGE_SIZE) });
|
|
27595
27712
|
if ("afterEventId" in cursor) query.set("afterEventId", cursor.afterEventId);
|
|
27596
27713
|
else query.set("afterTimestamp", String(cursor.afterTimestamp));
|
|
27714
|
+
const pollStartedAt = performance.now();
|
|
27597
27715
|
const page = await this.#client.request(
|
|
27598
27716
|
"GET",
|
|
27599
27717
|
`${API_PREFIX}/repositories/${repositoryId}/events?${query}`
|
|
27600
27718
|
);
|
|
27719
|
+
this.deps?.logger.info("Platform GitHub repository event poll completed", {
|
|
27720
|
+
repositoryId,
|
|
27721
|
+
eventCount: page.events.length,
|
|
27722
|
+
latencyMs: Math.round(performance.now() - pollStartedAt)
|
|
27723
|
+
});
|
|
27601
27724
|
if (page.events.length === 0 || !page.nextCursor) return;
|
|
27602
27725
|
for (const event of page.events) {
|
|
27603
27726
|
if (!this.#running || !this.#hasLease) return;
|
|
@@ -27720,6 +27843,7 @@ var PlatformGithubIntegration = class {
|
|
|
27720
27843
|
#storage;
|
|
27721
27844
|
#integrationStorage;
|
|
27722
27845
|
intake = {
|
|
27846
|
+
resolveIntakeDispatch: (input) => this.#resolveIntakeDispatch(input),
|
|
27723
27847
|
listSources: async ({ orgId, userId }) => {
|
|
27724
27848
|
const installations = await this.#client.request("GET", `${API_PREFIX2}/github-app/installations`);
|
|
27725
27849
|
const usable = installations.installations.filter(
|
|
@@ -27818,7 +27942,8 @@ var PlatformGithubIntegration = class {
|
|
|
27818
27942
|
return this.#listIssues(input.connection, sourceId, parsePositiveCursor(input.cursor), input.labels);
|
|
27819
27943
|
},
|
|
27820
27944
|
getIssue: (input) => this.#getIssue(input.connection, input.sourceId, input.issueId),
|
|
27821
|
-
createComment: (input) => this.#createIssueComment(input)
|
|
27945
|
+
createComment: (input) => this.#createIssueComment(input),
|
|
27946
|
+
updateIssue: (input) => this.#updateIntakeIssue(input)
|
|
27822
27947
|
};
|
|
27823
27948
|
versionControl = {
|
|
27824
27949
|
initialize: ({ storage }) => {
|
|
@@ -27910,6 +28035,21 @@ var PlatformGithubIntegration = class {
|
|
|
27910
28035
|
}
|
|
27911
28036
|
return this.#integrationStorage;
|
|
27912
28037
|
}
|
|
28038
|
+
/** Resolve a stored GitHub locator without scanning installations or repositories. */
|
|
28039
|
+
async #resolveIntakeDispatch({
|
|
28040
|
+
orgId,
|
|
28041
|
+
externalSource
|
|
28042
|
+
}) {
|
|
28043
|
+
const target = parseGithubExternalTarget(externalSource.externalId);
|
|
28044
|
+
if (!target) return null;
|
|
28045
|
+
const repository = target.repository.includes("/") ? target.repository : (await this.storage.repositories.findByExternalId({ orgId, externalId: target.repository }))?.slug;
|
|
28046
|
+
if (!repository) return null;
|
|
28047
|
+
return {
|
|
28048
|
+
connection: { type: "app-installation", installationId: 1 },
|
|
28049
|
+
sourceId: repository,
|
|
28050
|
+
issueId: target.issueId
|
|
28051
|
+
};
|
|
28052
|
+
}
|
|
27913
28053
|
initialize({ storage }) {
|
|
27914
28054
|
this.#integrationStorage = storage;
|
|
27915
28055
|
logPlatformInfo("Platform GitHub integration initialized", {
|
|
@@ -28208,6 +28348,39 @@ var PlatformGithubIntegration = class {
|
|
|
28208
28348
|
throw error;
|
|
28209
28349
|
}
|
|
28210
28350
|
}
|
|
28351
|
+
async #updateIntakeIssue(input) {
|
|
28352
|
+
requireGithubConnection(input.connection);
|
|
28353
|
+
const repository = requireSource(input.sourceId, "GitHub Intake requires a repository source.");
|
|
28354
|
+
const issueNumber = requirePositiveId(input.issueId, "issue");
|
|
28355
|
+
if (input.state.kind === "byName") {
|
|
28356
|
+
logPlatformWarn(`Platform GitHub: updateIssue byName is not supported (name=${input.state.name}); ignoring.`);
|
|
28357
|
+
return null;
|
|
28358
|
+
}
|
|
28359
|
+
const targetState = input.state.stateType === "unstarted" || input.state.stateType === "started" ? "open" : "closed";
|
|
28360
|
+
const stateReason = targetState === "closed" ? input.state.stateType === "canceled" ? "not_planned" : "completed" : null;
|
|
28361
|
+
try {
|
|
28362
|
+
await this.#client.request("GET", repositoryPath(repository, `pulls/${issueNumber}`));
|
|
28363
|
+
logPlatformWarn(`Platform GitHub: updateIssue rejected \u2014 target ${repository}#${issueNumber} is a pull request.`);
|
|
28364
|
+
return null;
|
|
28365
|
+
} catch (error) {
|
|
28366
|
+
if (!isNotFound(error)) throw error;
|
|
28367
|
+
}
|
|
28368
|
+
try {
|
|
28369
|
+
const issue = await this.#client.request(
|
|
28370
|
+
"PATCH",
|
|
28371
|
+
repositoryPath(repository, `issues/${issueNumber}`),
|
|
28372
|
+
{
|
|
28373
|
+
state: targetState,
|
|
28374
|
+
...stateReason ? { state_reason: stateReason } : {}
|
|
28375
|
+
},
|
|
28376
|
+
{ actingUserId: input.actingUserId }
|
|
28377
|
+
);
|
|
28378
|
+
return parseIntakeIssue(repository, issue);
|
|
28379
|
+
} catch (error) {
|
|
28380
|
+
if (isNotFound(error)) return null;
|
|
28381
|
+
throw error;
|
|
28382
|
+
}
|
|
28383
|
+
}
|
|
28211
28384
|
async #createIssueComment(input) {
|
|
28212
28385
|
requireGithubConnection(input.connection);
|
|
28213
28386
|
const repository = requireSource(input.sourceId, "GitHub Intake requires a repository source.");
|
|
@@ -28592,6 +28765,11 @@ function parsePositiveInteger(value) {
|
|
|
28592
28765
|
const parsed = Number(value);
|
|
28593
28766
|
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
|
|
28594
28767
|
}
|
|
28768
|
+
function parseGithubExternalTarget(externalId) {
|
|
28769
|
+
const match = externalId.match(/^(.+\/.+):(\d+)$/) ?? externalId.match(/^github:(\d+):(?:issue|pull-request):(\d+)$/) ?? externalId.match(/^(\d+):(\d+)$/);
|
|
28770
|
+
if (!match?.[1] || !match[2] || parsePositiveInteger(match[2]) === null) return null;
|
|
28771
|
+
return { repository: match[1], issueId: match[2] };
|
|
28772
|
+
}
|
|
28595
28773
|
function optionalPositiveIntegerEnv(name) {
|
|
28596
28774
|
const value = process.env[name]?.trim();
|
|
28597
28775
|
if (!value) return void 0;
|
|
@@ -28962,7 +29140,14 @@ var PlatformLinearIntegration = class {
|
|
|
28962
29140
|
#endpointHost;
|
|
28963
29141
|
#projects;
|
|
28964
29142
|
#auth;
|
|
29143
|
+
/**
|
|
29144
|
+
* Per-instance workflow-state cache keyed by `${workspaceId}:${teamId}`. Scoped to the process
|
|
29145
|
+
* lifetime; not shared across requests intentionally to keep failure modes simple (stale states
|
|
29146
|
+
* clear on process restart). Populated lazily on first `updateIssue` per team.
|
|
29147
|
+
*/
|
|
29148
|
+
#workflowStatesByTeam = /* @__PURE__ */ new Map();
|
|
28965
29149
|
intake = {
|
|
29150
|
+
resolveIntakeDispatch: (input) => this.#resolveIntakeDispatch(input),
|
|
28966
29151
|
listSources: async () => {
|
|
28967
29152
|
const sources = await this.#listProjectSources();
|
|
28968
29153
|
return sources.map(({ workspace, project }) => ({
|
|
@@ -29033,6 +29218,59 @@ var PlatformLinearIntegration = class {
|
|
|
29033
29218
|
if (isNotFound2(error)) return null;
|
|
29034
29219
|
throw error;
|
|
29035
29220
|
}
|
|
29221
|
+
},
|
|
29222
|
+
updateIssue: async (input) => {
|
|
29223
|
+
requireLinearConnection(input.connection);
|
|
29224
|
+
const located = await this.#findIssue(input.sourceId, input.issueId);
|
|
29225
|
+
if (!located) return null;
|
|
29226
|
+
const { workspaceId, issue } = located;
|
|
29227
|
+
const target = input.state;
|
|
29228
|
+
if (target.kind === "byType" && issue.state.type === target.stateType) {
|
|
29229
|
+
return parseIssue(issue);
|
|
29230
|
+
}
|
|
29231
|
+
if (target.kind === "byName" && issue.state.name.toLowerCase() === target.name.toLowerCase()) {
|
|
29232
|
+
return parseIssue(issue);
|
|
29233
|
+
}
|
|
29234
|
+
let states;
|
|
29235
|
+
try {
|
|
29236
|
+
states = await this.#listWorkflowStates(workspaceId, issue.team.id);
|
|
29237
|
+
} catch (error) {
|
|
29238
|
+
if (isNotFound2(error)) {
|
|
29239
|
+
logPlatformWarn("Platform Linear: workflow-states endpoint not available; skipping updateIssue.", {
|
|
29240
|
+
workspaceId,
|
|
29241
|
+
teamId: issue.team.id
|
|
29242
|
+
});
|
|
29243
|
+
return null;
|
|
29244
|
+
}
|
|
29245
|
+
throw error;
|
|
29246
|
+
}
|
|
29247
|
+
let matched;
|
|
29248
|
+
if (target.kind === "byType") {
|
|
29249
|
+
matched = states.slice().sort((a, b) => a.position - b.position).find((s) => s.type === target.stateType);
|
|
29250
|
+
} else {
|
|
29251
|
+
const wanted = target.name.toLowerCase();
|
|
29252
|
+
matched = states.find((s) => s.name.toLowerCase() === wanted);
|
|
29253
|
+
}
|
|
29254
|
+
if (!matched) {
|
|
29255
|
+
logPlatformWarn("Platform Linear: no workflow state matched target; skipping updateIssue.", {
|
|
29256
|
+
workspaceId,
|
|
29257
|
+
teamId: issue.team.id,
|
|
29258
|
+
target
|
|
29259
|
+
});
|
|
29260
|
+
return null;
|
|
29261
|
+
}
|
|
29262
|
+
try {
|
|
29263
|
+
await this.#client.request(
|
|
29264
|
+
"PATCH",
|
|
29265
|
+
`${API_PREFIX3}/workspaces/${encodeURIComponent(workspaceId)}/issues/${encodeURIComponent(input.issueId)}`,
|
|
29266
|
+
{ stateId: matched.id }
|
|
29267
|
+
);
|
|
29268
|
+
} catch (error) {
|
|
29269
|
+
if (isNotFound2(error)) return null;
|
|
29270
|
+
throw error;
|
|
29271
|
+
}
|
|
29272
|
+
const refreshed = await this.#findIssue(input.sourceId, input.issueId);
|
|
29273
|
+
return refreshed ? parseIssue(refreshed.issue) : null;
|
|
29036
29274
|
}
|
|
29037
29275
|
};
|
|
29038
29276
|
constructor() {
|
|
@@ -29105,6 +29343,23 @@ var PlatformLinearIntegration = class {
|
|
|
29105
29343
|
async getFreshAccessToken(_connection) {
|
|
29106
29344
|
return PLATFORM_MANAGED_CONNECTION_TOKEN;
|
|
29107
29345
|
}
|
|
29346
|
+
/**
|
|
29347
|
+
* Background-dispatch context: platform-managed connection token when the
|
|
29348
|
+
* org has a connected workspace. Linear work items store the issue UUID
|
|
29349
|
+
* directly as `externalId`.
|
|
29350
|
+
*/
|
|
29351
|
+
async #resolveIntakeDispatch({
|
|
29352
|
+
orgId,
|
|
29353
|
+
externalSource
|
|
29354
|
+
}) {
|
|
29355
|
+
if (externalSource.type !== "issue") return null;
|
|
29356
|
+
const connection = await this.loadConnection(orgId);
|
|
29357
|
+
if (!connection) return null;
|
|
29358
|
+
return {
|
|
29359
|
+
connection: { type: "oauth", accessToken: PLATFORM_MANAGED_CONNECTION_TOKEN },
|
|
29360
|
+
issueId: externalSource.externalId
|
|
29361
|
+
};
|
|
29362
|
+
}
|
|
29108
29363
|
canPostComments(connection) {
|
|
29109
29364
|
const scopes = (connection.scope ?? "").split(/[\s,]+/).filter(Boolean);
|
|
29110
29365
|
return scopes.some((scope) => scope === "comments:create" || scope === "write" || scope === "admin");
|
|
@@ -29264,6 +29519,17 @@ var PlatformLinearIntegration = class {
|
|
|
29264
29519
|
}
|
|
29265
29520
|
return null;
|
|
29266
29521
|
}
|
|
29522
|
+
async #listWorkflowStates(workspaceId, teamId) {
|
|
29523
|
+
const cacheKey = `${workspaceId}:${teamId}`;
|
|
29524
|
+
const cached = this.#workflowStatesByTeam.get(cacheKey);
|
|
29525
|
+
if (cached) return cached;
|
|
29526
|
+
const result = await this.#client.request(
|
|
29527
|
+
"GET",
|
|
29528
|
+
`${API_PREFIX3}/workspaces/${encodeURIComponent(workspaceId)}/workflow-states?teamId=${encodeURIComponent(teamId)}&first=100`
|
|
29529
|
+
);
|
|
29530
|
+
this.#workflowStatesByTeam.set(cacheKey, result.workflowStates);
|
|
29531
|
+
return result.workflowStates;
|
|
29532
|
+
}
|
|
29267
29533
|
async #candidateWorkspaceIds(sourceId) {
|
|
29268
29534
|
if (sourceId) return [decodeSourceId(sourceId).workspaceId];
|
|
29269
29535
|
return (await this.#listWorkspaces()).map((workspace) => workspace.linearWorkspaceId);
|
|
@@ -29769,6 +30035,7 @@ var ProjectRoutes = class extends Route {
|
|
|
29769
30035
|
orgId: tenant.orgId,
|
|
29770
30036
|
id: connection.installationId
|
|
29771
30037
|
});
|
|
30038
|
+
if (!installation) continue;
|
|
29772
30039
|
const links = await handle.projectRepositories.list({ orgId: tenant.orgId, connectionId: connection.id });
|
|
29773
30040
|
connections.push({
|
|
29774
30041
|
...connection,
|
|
@@ -31851,12 +32118,16 @@ var ConfigRoutes = class extends Route {
|
|
|
31851
32118
|
// src/routes/fs.ts
|
|
31852
32119
|
import { lstat, open, readdir, realpath, stat } from "fs/promises";
|
|
31853
32120
|
import { homedir } from "os";
|
|
31854
|
-
import { isAbsolute, join, resolve, sep } from "path";
|
|
32121
|
+
import { isAbsolute, join, posix as posixPath, resolve, sep } from "path";
|
|
32122
|
+
import { SandboxFilesystem } from "@mastra/code-sdk/agents/sandbox-filesystem";
|
|
31855
32123
|
import { detectProject, getResourceIdOverride } from "@mastra/code-sdk/utils/project";
|
|
31856
32124
|
import { registerApiRoute as registerApiRoute8 } from "@mastra/core/server";
|
|
31857
32125
|
var MAX_TEXT_FILE_BYTES = 512 * 1024;
|
|
31858
32126
|
var TEXT_DECODER = new TextDecoder("utf-8", { fatal: true });
|
|
31859
32127
|
var APPROVED_RENDERED_ROOTS = /* @__PURE__ */ new Set([".artifacts"]);
|
|
32128
|
+
function loose7(c) {
|
|
32129
|
+
return c;
|
|
32130
|
+
}
|
|
31860
32131
|
function resolveFsRoot(root) {
|
|
31861
32132
|
return resolve(root && root.trim() ? root : homedir());
|
|
31862
32133
|
}
|
|
@@ -32037,6 +32308,91 @@ async function listArtifacts(root, workspacePath) {
|
|
|
32037
32308
|
entries: listing.entries
|
|
32038
32309
|
};
|
|
32039
32310
|
}
|
|
32311
|
+
async function resolveAuthorizedSession(c, deps, workspacePath) {
|
|
32312
|
+
if (!deps) return null;
|
|
32313
|
+
const session = await deps.sessions.getBySessionId(workspacePath);
|
|
32314
|
+
if (!session) return null;
|
|
32315
|
+
if (deps.auth.enabled()) {
|
|
32316
|
+
await deps.auth.ensureUser(c);
|
|
32317
|
+
const tenant = deps.auth.tenant(c);
|
|
32318
|
+
if (!tenant || tenant.orgId !== session.orgId || tenant.userId !== session.userId) {
|
|
32319
|
+
throw new Error("Session is not available to the current user");
|
|
32320
|
+
}
|
|
32321
|
+
}
|
|
32322
|
+
return session;
|
|
32323
|
+
}
|
|
32324
|
+
async function sessionSandbox(fleet, session) {
|
|
32325
|
+
if (!fleet.enabled || !session.sandboxId || !session.sandboxWorkdir) return null;
|
|
32326
|
+
let sandbox;
|
|
32327
|
+
try {
|
|
32328
|
+
sandbox = await fleet.reattachSandbox(session.sandboxId, { workingDirectory: session.sandboxWorkdir });
|
|
32329
|
+
} catch {
|
|
32330
|
+
return null;
|
|
32331
|
+
}
|
|
32332
|
+
return {
|
|
32333
|
+
sandbox,
|
|
32334
|
+
filesystem: new SandboxFilesystem({ sandbox, workdir: session.sandboxWorkdir }),
|
|
32335
|
+
workdir: session.sandboxWorkdir
|
|
32336
|
+
};
|
|
32337
|
+
}
|
|
32338
|
+
async function listSessionRenderedPath(fleet, session, renderedRoot) {
|
|
32339
|
+
const safeRoot = assertApprovedRenderedRoot(renderedRoot);
|
|
32340
|
+
const rootPath = posixPath.join(session.sandboxWorkdir ?? "", safeRoot);
|
|
32341
|
+
const empty = { workspacePath: session.sessionId, root: safeRoot, rootPath, entries: [] };
|
|
32342
|
+
const handle = await sessionSandbox(fleet, session);
|
|
32343
|
+
if (!handle) return empty;
|
|
32344
|
+
const quotedRoot = `'${rootPath.replace(/'/g, `'\\''`)}'`;
|
|
32345
|
+
const result = await handle.sandbox.executeCommand(
|
|
32346
|
+
"sh",
|
|
32347
|
+
[
|
|
32348
|
+
"-c",
|
|
32349
|
+
`test -d ${quotedRoot} && find ${quotedRoot} -mindepth 1 -printf '%y\\t%s\\t%T@\\t%p\\n' 2>/dev/null || true`
|
|
32350
|
+
],
|
|
32351
|
+
{ timeout: 3e4 }
|
|
32352
|
+
);
|
|
32353
|
+
if (result.exitCode !== 0) return empty;
|
|
32354
|
+
const entries = [];
|
|
32355
|
+
for (const line of result.stdout.split("\n")) {
|
|
32356
|
+
if (!line) continue;
|
|
32357
|
+
const [type, sizeStr, mtimeStr, ...pathParts] = line.split(" ");
|
|
32358
|
+
const fullPath = pathParts.join(" ");
|
|
32359
|
+
if (!fullPath || !fullPath.startsWith(`${rootPath}/`)) continue;
|
|
32360
|
+
const relativePath = fullPath.slice(rootPath.length + 1);
|
|
32361
|
+
entries.push({
|
|
32362
|
+
name: posixPath.basename(relativePath),
|
|
32363
|
+
path: relativePath,
|
|
32364
|
+
type: type === "d" ? "directory" : "file",
|
|
32365
|
+
size: type === "d" ? 0 : Number(sizeStr) || 0,
|
|
32366
|
+
updatedAt: new Date((Number(mtimeStr) || 0) * 1e3).toISOString()
|
|
32367
|
+
});
|
|
32368
|
+
}
|
|
32369
|
+
entries.sort((a, b) => a.path.localeCompare(b.path));
|
|
32370
|
+
return { workspacePath: session.sessionId, root: safeRoot, rootPath, entries };
|
|
32371
|
+
}
|
|
32372
|
+
async function readSessionWorkspaceFile(fleet, session, path3) {
|
|
32373
|
+
const safePath = assertRelativePath(path3, "path");
|
|
32374
|
+
assertApprovedRenderedRoot(safePath.split("/")[0] ?? "");
|
|
32375
|
+
const handle = await sessionSandbox(fleet, session);
|
|
32376
|
+
if (!handle) throw new Error("Session workspace is not available");
|
|
32377
|
+
const { filesystem } = handle;
|
|
32378
|
+
const info = await filesystem.stat(safePath);
|
|
32379
|
+
if (info.type === "directory") throw new Error("Path is a directory");
|
|
32380
|
+
const buffer = await filesystem.readFile(safePath);
|
|
32381
|
+
const truncated = buffer.length > MAX_TEXT_FILE_BYTES;
|
|
32382
|
+
const base = {
|
|
32383
|
+
workspacePath: session.sessionId,
|
|
32384
|
+
path: safePath,
|
|
32385
|
+
name: posixPath.basename(safePath),
|
|
32386
|
+
size: buffer.length,
|
|
32387
|
+
updatedAt: info.modifiedAt.toISOString()
|
|
32388
|
+
};
|
|
32389
|
+
try {
|
|
32390
|
+
const content = TEXT_DECODER.decode(truncated ? buffer.subarray(0, MAX_TEXT_FILE_BYTES) : buffer);
|
|
32391
|
+
return { ...base, contentType: "text", content, truncated };
|
|
32392
|
+
} catch {
|
|
32393
|
+
return { ...base, contentType: "unsupported" };
|
|
32394
|
+
}
|
|
32395
|
+
}
|
|
32040
32396
|
function resolveCodebase(projectPath) {
|
|
32041
32397
|
const info = detectProject(projectPath);
|
|
32042
32398
|
const override = getResourceIdOverride(info.rootPath);
|
|
@@ -32050,6 +32406,7 @@ function resolveCodebase(projectPath) {
|
|
|
32050
32406
|
}
|
|
32051
32407
|
function buildFsRoutes(options = {}) {
|
|
32052
32408
|
const root = resolveFsRoot(options.root);
|
|
32409
|
+
const sessionFs = options.sessionFs;
|
|
32053
32410
|
return [
|
|
32054
32411
|
registerApiRoute8("/web/fs/list", {
|
|
32055
32412
|
method: "GET",
|
|
@@ -32089,10 +32446,14 @@ function buildFsRoutes(options = {}) {
|
|
|
32089
32446
|
if (!workspacePath) return c.json({ error: "Missing required query param: workspacePath" }, 400);
|
|
32090
32447
|
if (!renderedRoot) return c.json({ error: "Missing required query param: root" }, 400);
|
|
32091
32448
|
try {
|
|
32449
|
+
const session = await resolveAuthorizedSession(loose7(c), sessionFs, workspacePath);
|
|
32450
|
+
if (session && sessionFs) {
|
|
32451
|
+
return c.json(await listSessionRenderedPath(sessionFs.fleet, session, renderedRoot));
|
|
32452
|
+
}
|
|
32092
32453
|
return c.json(await listWorkspaceRenderedPath(root, workspacePath, renderedRoot));
|
|
32093
32454
|
} catch (error) {
|
|
32094
32455
|
const message = error instanceof Error ? error.message : String(error);
|
|
32095
|
-
const status = message.includes("outside") || message.includes("relative") || message.includes("escapes") || message.includes("not approved") ? 403 : 500;
|
|
32456
|
+
const status = message.includes("outside") || message.includes("relative") || message.includes("escapes") || message.includes("not approved") || message.includes("not available") ? 403 : 500;
|
|
32096
32457
|
return c.json({ error: message }, status);
|
|
32097
32458
|
}
|
|
32098
32459
|
}
|
|
@@ -32106,10 +32467,14 @@ function buildFsRoutes(options = {}) {
|
|
|
32106
32467
|
if (!workspacePath) return c.json({ error: "Missing required query param: workspacePath" }, 400);
|
|
32107
32468
|
if (!path3) return c.json({ error: "Missing required query param: path" }, 400);
|
|
32108
32469
|
try {
|
|
32470
|
+
const session = await resolveAuthorizedSession(loose7(c), sessionFs, workspacePath);
|
|
32471
|
+
if (session && sessionFs) {
|
|
32472
|
+
return c.json(await readSessionWorkspaceFile(sessionFs.fleet, session, path3));
|
|
32473
|
+
}
|
|
32109
32474
|
return c.json(await readWorkspaceFile(root, workspacePath, path3));
|
|
32110
32475
|
} catch (error) {
|
|
32111
32476
|
const message = error instanceof Error ? error.message : String(error);
|
|
32112
|
-
const status = message.includes("outside") || message.includes("relative") || message.includes("escapes") || message.includes("not approved") ? 403 : message.includes("directory") ? 400 : 500;
|
|
32477
|
+
const status = message.includes("outside") || message.includes("relative") || message.includes("escapes") || message.includes("not approved") || message.includes("not available") ? 403 : message.includes("directory") ? 400 : message.includes("not found") ? 404 : 500;
|
|
32113
32478
|
return c.json({ error: message }, status);
|
|
32114
32479
|
}
|
|
32115
32480
|
}
|
|
@@ -32135,7 +32500,7 @@ function buildFsRoutes(options = {}) {
|
|
|
32135
32500
|
|
|
32136
32501
|
// src/routes/intake.ts
|
|
32137
32502
|
import { registerApiRoute as registerApiRoute9 } from "@mastra/core/server";
|
|
32138
|
-
function
|
|
32503
|
+
function loose8(c) {
|
|
32139
32504
|
return c;
|
|
32140
32505
|
}
|
|
32141
32506
|
function sanitizeIdList(value) {
|
|
@@ -32199,7 +32564,7 @@ var IntakeRoutes = class extends Route {
|
|
|
32199
32564
|
method: "GET",
|
|
32200
32565
|
requiresAuth: false,
|
|
32201
32566
|
handler: async (c) => {
|
|
32202
|
-
const tenant = await this.#resolveTenant(
|
|
32567
|
+
const tenant = await this.#resolveTenant(loose8(c));
|
|
32203
32568
|
if ("response" in tenant) return tenant.response;
|
|
32204
32569
|
await intake.ensureReady();
|
|
32205
32570
|
const config = await intake.getConfig({ ...tenant, integrationIds });
|
|
@@ -32210,7 +32575,7 @@ var IntakeRoutes = class extends Route {
|
|
|
32210
32575
|
method: "PUT",
|
|
32211
32576
|
requiresAuth: false,
|
|
32212
32577
|
handler: async (c) => {
|
|
32213
|
-
const tenant = await this.#resolveTenant(
|
|
32578
|
+
const tenant = await this.#resolveTenant(loose8(c));
|
|
32214
32579
|
if ("response" in tenant) return tenant.response;
|
|
32215
32580
|
let body;
|
|
32216
32581
|
try {
|
|
@@ -32225,7 +32590,7 @@ var IntakeRoutes = class extends Route {
|
|
|
32225
32590
|
await intake.ensureReady();
|
|
32226
32591
|
await intake.saveConfig({ ...tenant, config });
|
|
32227
32592
|
await audit.emit({
|
|
32228
|
-
context:
|
|
32593
|
+
context: loose8(c),
|
|
32229
32594
|
input: {
|
|
32230
32595
|
action: "factory.intake.config_updated",
|
|
32231
32596
|
targets: [{ type: "intake_config", id: tenant.orgId }],
|
|
@@ -32244,7 +32609,7 @@ var IntakeRoutes = class extends Route {
|
|
|
32244
32609
|
method: "GET",
|
|
32245
32610
|
requiresAuth: false,
|
|
32246
32611
|
handler: async (c) => {
|
|
32247
|
-
const tenant = await this.#resolveTenant(
|
|
32612
|
+
const tenant = await this.#resolveTenant(loose8(c));
|
|
32248
32613
|
if ("response" in tenant) return tenant.response;
|
|
32249
32614
|
const pages = await Promise.all(
|
|
32250
32615
|
integrations.map(async (integration) => ({
|
|
@@ -32263,7 +32628,7 @@ var IntakeRoutes = class extends Route {
|
|
|
32263
32628
|
method: "GET",
|
|
32264
32629
|
requiresAuth: false,
|
|
32265
32630
|
handler: async (c) => {
|
|
32266
|
-
const tenant = await this.#resolveTenant(
|
|
32631
|
+
const tenant = await this.#resolveTenant(loose8(c));
|
|
32267
32632
|
if ("response" in tenant) return tenant.response;
|
|
32268
32633
|
const cursors = decodeCursor2(c.req.query("cursor"));
|
|
32269
32634
|
if (!cursors) return c.json({ error: "invalid_cursor" }, 400);
|
|
@@ -32642,7 +33007,7 @@ var OAUTH_FLOWS = {
|
|
|
32642
33007
|
}
|
|
32643
33008
|
}
|
|
32644
33009
|
};
|
|
32645
|
-
function
|
|
33010
|
+
function loose9(c) {
|
|
32646
33011
|
return c;
|
|
32647
33012
|
}
|
|
32648
33013
|
var localSessionsPromise;
|
|
@@ -32712,14 +33077,14 @@ var OAuthRoutes = class extends Route {
|
|
|
32712
33077
|
method: "POST",
|
|
32713
33078
|
requiresAuth: false,
|
|
32714
33079
|
handler: async (c) => {
|
|
32715
|
-
const ctx = await resolveCredentialContext({ c:
|
|
33080
|
+
const ctx = await resolveCredentialContext({ c: loose9(c), auth, credentials: modelCredentials });
|
|
32716
33081
|
if ("response" in ctx) return ctx.response;
|
|
32717
33082
|
const provider = c.req.param("provider");
|
|
32718
33083
|
const flow = OAUTH_FLOWS[provider];
|
|
32719
33084
|
if (!flow) {
|
|
32720
33085
|
return c.json({ error: "oauth_not_supported", message: `Provider does not support web sign-in` }, 404);
|
|
32721
33086
|
}
|
|
32722
|
-
const body = await readJsonBody(
|
|
33087
|
+
const body = await readJsonBody(loose9(c));
|
|
32723
33088
|
if (typeof body.mode === "string" && body.mode !== flow.kind) {
|
|
32724
33089
|
return c.json({ error: "invalid_mode", message: `Unsupported mode for ${provider}: ${body.mode}` }, 400);
|
|
32725
33090
|
}
|
|
@@ -32756,12 +33121,12 @@ var OAuthRoutes = class extends Route {
|
|
|
32756
33121
|
method: "POST",
|
|
32757
33122
|
requiresAuth: false,
|
|
32758
33123
|
handler: async (c) => {
|
|
32759
|
-
const ctx = await resolveCredentialContext({ c:
|
|
33124
|
+
const ctx = await resolveCredentialContext({ c: loose9(c), auth, credentials: modelCredentials });
|
|
32760
33125
|
if ("response" in ctx) return ctx.response;
|
|
32761
33126
|
const provider = c.req.param("provider");
|
|
32762
33127
|
const flow = OAUTH_FLOWS[provider];
|
|
32763
33128
|
if (!flow?.complete) return c.json({ error: "oauth_not_supported" }, 404);
|
|
32764
|
-
const body = await readJsonBody(
|
|
33129
|
+
const body = await readJsonBody(loose9(c));
|
|
32765
33130
|
const sessionId = typeof body.sessionId === "string" ? body.sessionId : "";
|
|
32766
33131
|
const code = typeof body.code === "string" ? body.code.trim() : "";
|
|
32767
33132
|
if (!sessionId || !code) return c.json({ error: "Missing required fields: sessionId, code" }, 400);
|
|
@@ -32791,12 +33156,12 @@ var OAuthRoutes = class extends Route {
|
|
|
32791
33156
|
method: "POST",
|
|
32792
33157
|
requiresAuth: false,
|
|
32793
33158
|
handler: async (c) => {
|
|
32794
|
-
const ctx = await resolveCredentialContext({ c:
|
|
33159
|
+
const ctx = await resolveCredentialContext({ c: loose9(c), auth, credentials: modelCredentials });
|
|
32795
33160
|
if ("response" in ctx) return ctx.response;
|
|
32796
33161
|
const provider = c.req.param("provider");
|
|
32797
33162
|
const flow = OAUTH_FLOWS[provider];
|
|
32798
33163
|
if (!flow?.poll) return c.json({ error: "oauth_not_supported" }, 404);
|
|
32799
|
-
const body = await readJsonBody(
|
|
33164
|
+
const body = await readJsonBody(loose9(c));
|
|
32800
33165
|
const sessionId = typeof body.sessionId === "string" ? body.sessionId : "";
|
|
32801
33166
|
if (!sessionId) return c.json({ error: "Missing required field: sessionId" }, 400);
|
|
32802
33167
|
const session = await loadOwnedSession({ ctx, provider, sessionId });
|
|
@@ -32847,7 +33212,7 @@ var OAuthRoutes = class extends Route {
|
|
|
32847
33212
|
method: "DELETE",
|
|
32848
33213
|
requiresAuth: false,
|
|
32849
33214
|
handler: async (c) => {
|
|
32850
|
-
const ctx = await resolveCredentialContext({ c:
|
|
33215
|
+
const ctx = await resolveCredentialContext({ c: loose9(c), auth, credentials: modelCredentials });
|
|
32851
33216
|
if ("response" in ctx) return ctx.response;
|
|
32852
33217
|
const provider = c.req.param("provider");
|
|
32853
33218
|
const sessionId = c.req.param("sessionId");
|
|
@@ -32860,7 +33225,7 @@ var OAuthRoutes = class extends Route {
|
|
|
32860
33225
|
method: "DELETE",
|
|
32861
33226
|
requiresAuth: false,
|
|
32862
33227
|
handler: async (c) => {
|
|
32863
|
-
const ctx = await resolveCredentialContext({ c:
|
|
33228
|
+
const ctx = await resolveCredentialContext({ c: loose9(c), auth, credentials: modelCredentials });
|
|
32864
33229
|
if ("response" in ctx) return ctx.response;
|
|
32865
33230
|
const provider = c.req.param("provider");
|
|
32866
33231
|
const authProviderId = getAuthProviderId(provider);
|
|
@@ -32926,7 +33291,7 @@ var MAX_SCOPE_LENGTH = 2048;
|
|
|
32926
33291
|
var MAX_ARGUMENTS_LENGTH2 = 16384;
|
|
32927
33292
|
var SKILL_NAME_RE2 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
32928
33293
|
var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
32929
|
-
function
|
|
33294
|
+
function loose10(context) {
|
|
32930
33295
|
return context;
|
|
32931
33296
|
}
|
|
32932
33297
|
function parseBody(value) {
|
|
@@ -33000,7 +33365,7 @@ var SkillRoutes = class extends Route {
|
|
|
33000
33365
|
const { controllerId, controller, authorizeSessionAddress: customAuthorize } = this.deps;
|
|
33001
33366
|
const authorize = customAuthorize ?? ((context, address) => this.#authorizeSessionAddress(context, address));
|
|
33002
33367
|
const handleSkillRequest = async (context, dispatch) => {
|
|
33003
|
-
const c =
|
|
33368
|
+
const c = loose10(context);
|
|
33004
33369
|
if (c.req.param("controllerId") !== controllerId) {
|
|
33005
33370
|
return c.json({ error: "controller_not_found", message: "Agent controller not found." }, 404);
|
|
33006
33371
|
}
|
|
@@ -34627,7 +34992,7 @@ function computeFactoryMetrics(items, opts) {
|
|
|
34627
34992
|
}
|
|
34628
34993
|
|
|
34629
34994
|
// src/routes/work-items.ts
|
|
34630
|
-
function
|
|
34995
|
+
function loose11(c) {
|
|
34631
34996
|
return c;
|
|
34632
34997
|
}
|
|
34633
34998
|
var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -34945,7 +35310,7 @@ var WorkItemRoutes = class extends Route {
|
|
|
34945
35310
|
method: "GET",
|
|
34946
35311
|
requiresAuth: false,
|
|
34947
35312
|
handler: async (c) => {
|
|
34948
|
-
const resolved = await this.#resolveProject(
|
|
35313
|
+
const resolved = await this.#resolveProject(loose11(c));
|
|
34949
35314
|
if ("response" in resolved) return resolved.response;
|
|
34950
35315
|
await workItems.ensureReady();
|
|
34951
35316
|
const items = await workItems.list({
|
|
@@ -34960,11 +35325,11 @@ var WorkItemRoutes = class extends Route {
|
|
|
34960
35325
|
method: "GET",
|
|
34961
35326
|
requiresAuth: false,
|
|
34962
35327
|
handler: async (c) => {
|
|
34963
|
-
const resolved = await this.#resolveProject(
|
|
35328
|
+
const resolved = await this.#resolveProject(loose11(c));
|
|
34964
35329
|
if ("response" in resolved) return resolved.response;
|
|
34965
35330
|
const { windowStart, windowEnd } = parseMetricsRange(
|
|
34966
|
-
|
|
34967
|
-
|
|
35331
|
+
loose11(c).req.query("from"),
|
|
35332
|
+
loose11(c).req.query("to"),
|
|
34968
35333
|
/* @__PURE__ */ new Date()
|
|
34969
35334
|
);
|
|
34970
35335
|
await workItems.ensureReady();
|
|
@@ -34980,7 +35345,7 @@ var WorkItemRoutes = class extends Route {
|
|
|
34980
35345
|
method: "GET",
|
|
34981
35346
|
requiresAuth: false,
|
|
34982
35347
|
handler: async (c) => {
|
|
34983
|
-
const resolved = await this.#resolveProject(
|
|
35348
|
+
const resolved = await this.#resolveProject(loose11(c));
|
|
34984
35349
|
if ("response" in resolved) return resolved.response;
|
|
34985
35350
|
await queueHealth.ensureReady();
|
|
34986
35351
|
const stored = await queueHealth.getConfig(resolved.orgId, resolved.factoryProjectId);
|
|
@@ -34992,7 +35357,7 @@ var WorkItemRoutes = class extends Route {
|
|
|
34992
35357
|
method: "GET",
|
|
34993
35358
|
requiresAuth: false,
|
|
34994
35359
|
handler: async (c) => {
|
|
34995
|
-
const context =
|
|
35360
|
+
const context = loose11(c);
|
|
34996
35361
|
const resolved = await this.#resolveProject(context);
|
|
34997
35362
|
if ("response" in resolved) return resolved.response;
|
|
34998
35363
|
const cursorRaw = context.req.query("before");
|
|
@@ -35017,7 +35382,7 @@ var WorkItemRoutes = class extends Route {
|
|
|
35017
35382
|
method: "POST",
|
|
35018
35383
|
requiresAuth: false,
|
|
35019
35384
|
handler: async (c) => {
|
|
35020
|
-
const context =
|
|
35385
|
+
const context = loose11(c);
|
|
35021
35386
|
const resolved = await this.#resolveProject(context);
|
|
35022
35387
|
if ("response" in resolved) return resolved.response;
|
|
35023
35388
|
const decisionId = context.req.param("decisionId");
|
|
@@ -35038,9 +35403,9 @@ var WorkItemRoutes = class extends Route {
|
|
|
35038
35403
|
method: "POST",
|
|
35039
35404
|
requiresAuth: false,
|
|
35040
35405
|
handler: async (c) => {
|
|
35041
|
-
const resolved = await this.#resolveProject(
|
|
35406
|
+
const resolved = await this.#resolveProject(loose11(c));
|
|
35042
35407
|
if ("response" in resolved) return resolved.response;
|
|
35043
|
-
const body = await readJson2(
|
|
35408
|
+
const body = await readJson2(loose11(c));
|
|
35044
35409
|
if (body === void 0) return c.json({ error: "Invalid JSON body" }, 400);
|
|
35045
35410
|
const input = parseCreateWorkItem(body);
|
|
35046
35411
|
if (!input) return c.json({ error: "invalid_work_item" }, 400);
|
|
@@ -35083,7 +35448,7 @@ var WorkItemRoutes = class extends Route {
|
|
|
35083
35448
|
}
|
|
35084
35449
|
item = await workItems.getForProject(resolved.orgId, resolved.factoryProjectId, item.id) ?? item;
|
|
35085
35450
|
await audit.emit({
|
|
35086
|
-
context:
|
|
35451
|
+
context: loose11(c),
|
|
35087
35452
|
input: {
|
|
35088
35453
|
action: "factory.work_item.created",
|
|
35089
35454
|
factoryProjectId: resolved.factoryProjectId,
|
|
@@ -35094,7 +35459,7 @@ var WorkItemRoutes = class extends Route {
|
|
|
35094
35459
|
} else {
|
|
35095
35460
|
const { stages: _stages, sessions: _sessions, ...boundedPatch } = input;
|
|
35096
35461
|
await this.#auditWorkItemPatch({
|
|
35097
|
-
context:
|
|
35462
|
+
context: loose11(c),
|
|
35098
35463
|
item,
|
|
35099
35464
|
previous: result.previous,
|
|
35100
35465
|
patch: boundedPatch
|
|
@@ -35114,11 +35479,11 @@ var WorkItemRoutes = class extends Route {
|
|
|
35114
35479
|
method: "POST",
|
|
35115
35480
|
requiresAuth: false,
|
|
35116
35481
|
handler: async (c) => {
|
|
35117
|
-
const resolved = await this.#resolveProject(
|
|
35482
|
+
const resolved = await this.#resolveProject(loose11(c));
|
|
35118
35483
|
if ("response" in resolved) return resolved.response;
|
|
35119
|
-
const workItemId =
|
|
35484
|
+
const workItemId = loose11(c).req.param("workItemId");
|
|
35120
35485
|
if (!workItemId || !UUID_RE4.test(workItemId)) return c.json({ error: "Work item not found" }, 404);
|
|
35121
|
-
const parsed = parseTransitionBody(await readJson2(
|
|
35486
|
+
const parsed = parseTransitionBody(await readJson2(loose11(c)));
|
|
35122
35487
|
if (!parsed) return c.json({ error: "invalid_transition_request" }, 400);
|
|
35123
35488
|
if (!transitionService) {
|
|
35124
35489
|
return c.json({ error: "factory_transition_unavailable" }, 503);
|
|
@@ -35136,7 +35501,7 @@ var WorkItemRoutes = class extends Route {
|
|
|
35136
35501
|
}
|
|
35137
35502
|
});
|
|
35138
35503
|
await audit.emit({
|
|
35139
|
-
context:
|
|
35504
|
+
context: loose11(c),
|
|
35140
35505
|
input: {
|
|
35141
35506
|
action: result.status === "accepted" ? "factory.work_item.stage_moved" : "factory.work_item.transition_rejected",
|
|
35142
35507
|
factoryProjectId: resolved.factoryProjectId,
|
|
@@ -35158,14 +35523,14 @@ var WorkItemRoutes = class extends Route {
|
|
|
35158
35523
|
method: "POST",
|
|
35159
35524
|
requiresAuth: false,
|
|
35160
35525
|
handler: async (c) => {
|
|
35161
|
-
const resolved = await this.#resolveProject(
|
|
35526
|
+
const resolved = await this.#resolveProject(loose11(c));
|
|
35162
35527
|
if ("response" in resolved) return resolved.response;
|
|
35163
35528
|
if (!startCoordinator) {
|
|
35164
35529
|
return c.json({ error: "factory_start_unavailable" }, 503);
|
|
35165
35530
|
}
|
|
35166
|
-
const input = parseStartBody(await readJson2(
|
|
35531
|
+
const input = parseStartBody(await readJson2(loose11(c)), resolved, resolved.factoryProjectId);
|
|
35167
35532
|
if (!input) return c.json({ error: "invalid_factory_start" }, 400);
|
|
35168
|
-
input.requestContext =
|
|
35533
|
+
input.requestContext = loose11(c).get("requestContext");
|
|
35169
35534
|
input.defaultModelId = resolved.defaultModelId ?? void 0;
|
|
35170
35535
|
if (!input.workItem.id && ((input.workItem.input.stages ?? ["intake"]).length !== 1 || (input.workItem.input.stages ?? ["intake"])[0] !== "intake")) {
|
|
35171
35536
|
return c.json(
|
|
@@ -35184,7 +35549,7 @@ var WorkItemRoutes = class extends Route {
|
|
|
35184
35549
|
throw error;
|
|
35185
35550
|
}
|
|
35186
35551
|
await audit.emit({
|
|
35187
|
-
context:
|
|
35552
|
+
context: loose11(c),
|
|
35188
35553
|
input: {
|
|
35189
35554
|
action: "factory.run.started",
|
|
35190
35555
|
factoryProjectId: resolved.factoryProjectId,
|
|
@@ -35206,11 +35571,11 @@ var WorkItemRoutes = class extends Route {
|
|
|
35206
35571
|
method: "PATCH",
|
|
35207
35572
|
requiresAuth: false,
|
|
35208
35573
|
handler: async (c) => {
|
|
35209
|
-
const tenant = await this.#resolveTenant(
|
|
35574
|
+
const tenant = await this.#resolveTenant(loose11(c));
|
|
35210
35575
|
if ("response" in tenant) return tenant.response;
|
|
35211
|
-
const id =
|
|
35576
|
+
const id = loose11(c).req.param("id");
|
|
35212
35577
|
if (!id || !UUID_RE4.test(id)) return c.json({ error: "Work item not found" }, 404);
|
|
35213
|
-
const body = await readJson2(
|
|
35578
|
+
const body = await readJson2(loose11(c));
|
|
35214
35579
|
if (body === void 0) return c.json({ error: "Invalid JSON body" }, 400);
|
|
35215
35580
|
const patch = parseUpdateWorkItem(body);
|
|
35216
35581
|
if (!patch) return c.json({ error: "invalid_work_item_patch" }, 400);
|
|
@@ -35225,7 +35590,7 @@ var WorkItemRoutes = class extends Route {
|
|
|
35225
35590
|
const updated = await workItems.update({ orgId: tenant.orgId, id, userId: tenant.userId, patch });
|
|
35226
35591
|
if (!updated) return c.json({ error: "Work item not found" }, 404);
|
|
35227
35592
|
await this.#auditWorkItemPatch({
|
|
35228
|
-
context:
|
|
35593
|
+
context: loose11(c),
|
|
35229
35594
|
item: updated.item,
|
|
35230
35595
|
previous: updated.previous,
|
|
35231
35596
|
patch
|
|
@@ -35244,15 +35609,15 @@ var WorkItemRoutes = class extends Route {
|
|
|
35244
35609
|
method: "DELETE",
|
|
35245
35610
|
requiresAuth: false,
|
|
35246
35611
|
handler: async (c) => {
|
|
35247
|
-
const tenant = await this.#resolveTenant(
|
|
35612
|
+
const tenant = await this.#resolveTenant(loose11(c));
|
|
35248
35613
|
if ("response" in tenant) return tenant.response;
|
|
35249
|
-
const id =
|
|
35614
|
+
const id = loose11(c).req.param("id");
|
|
35250
35615
|
if (!id || !UUID_RE4.test(id)) return c.json({ error: "Work item not found" }, 404);
|
|
35251
35616
|
await workItems.ensureReady();
|
|
35252
35617
|
const deleted = await workItems.delete({ orgId: tenant.orgId, id });
|
|
35253
35618
|
if (!deleted) return c.json({ error: "Work item not found" }, 404);
|
|
35254
35619
|
await audit.emit({
|
|
35255
|
-
context:
|
|
35620
|
+
context: loose11(c),
|
|
35256
35621
|
input: {
|
|
35257
35622
|
action: "factory.work_item.deleted",
|
|
35258
35623
|
factoryProjectId: deleted.factoryProjectId,
|
|
@@ -35473,7 +35838,14 @@ function assembleFactoryApiRoutes(deps) {
|
|
|
35473
35838
|
});
|
|
35474
35839
|
}
|
|
35475
35840
|
return [
|
|
35476
|
-
...buildFsRoutes({
|
|
35841
|
+
...buildFsRoutes({
|
|
35842
|
+
root: deps.fsRoot,
|
|
35843
|
+
sessionFs: {
|
|
35844
|
+
auth: deps.auth,
|
|
35845
|
+
fleet: deps.fleet,
|
|
35846
|
+
sessions: deps.sourceControlStorage.forIntegration("github").sessions
|
|
35847
|
+
}
|
|
35848
|
+
}),
|
|
35477
35849
|
...new ConfigRoutes({
|
|
35478
35850
|
auth: deps.auth,
|
|
35479
35851
|
controller: deps.controller,
|
|
@@ -36627,7 +36999,7 @@ function handleServerError(err, c) {
|
|
|
36627
36999
|
return c.json({ error: err.message }, err.status);
|
|
36628
37000
|
}
|
|
36629
37001
|
const detail = err instanceof Error ? err.stack ?? err.message : String(err);
|
|
36630
|
-
console.error(`[
|
|
37002
|
+
console.error(`[Mastra Factory] ${c.req.method} ${c.req.path} failed: ${detail}`);
|
|
36631
37003
|
return c.json(
|
|
36632
37004
|
{
|
|
36633
37005
|
error: "internal_error",
|
|
@@ -36939,7 +37311,7 @@ var AuditStorage = class extends FactoryStorageDomain4 {
|
|
|
36939
37311
|
import { registerApiRoute as registerApiRoute14 } from "@mastra/core/server";
|
|
36940
37312
|
var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
36941
37313
|
var MAX_ACTION_FILTERS = 16;
|
|
36942
|
-
function
|
|
37314
|
+
function loose12(c) {
|
|
36943
37315
|
return c;
|
|
36944
37316
|
}
|
|
36945
37317
|
function parseActionsParam(raw) {
|
|
@@ -37062,7 +37434,7 @@ var AuditDomain = class {
|
|
|
37062
37434
|
registerApiRoute14("/web/factory/projects/:id/audit", {
|
|
37063
37435
|
method: "GET",
|
|
37064
37436
|
handler: async (cc) => {
|
|
37065
|
-
const c =
|
|
37437
|
+
const c = loose12(cc);
|
|
37066
37438
|
const tenant = await this.#resolveTenant(c);
|
|
37067
37439
|
if ("response" in tenant) return tenant.response;
|
|
37068
37440
|
const projectId = c.req.param("id");
|
|
@@ -38228,13 +38600,12 @@ var SourceControlStorage = class extends FactoryStorageDomain11 {
|
|
|
38228
38600
|
);
|
|
38229
38601
|
},
|
|
38230
38602
|
get: getRepository,
|
|
38231
|
-
findByExternalId: async ({ orgId,
|
|
38232
|
-
await
|
|
38233
|
-
const row
|
|
38234
|
-
|
|
38235
|
-
|
|
38236
|
-
|
|
38237
|
-
return row ? toRepository(row) : null;
|
|
38603
|
+
findByExternalId: async ({ orgId, externalId }) => {
|
|
38604
|
+
const rows = await db().findMany(REPOSITORIES, { external_id: externalId });
|
|
38605
|
+
for (const row of rows) {
|
|
38606
|
+
if (await getInstallation({ orgId, id: row.installation_id })) return toRepository(row);
|
|
38607
|
+
}
|
|
38608
|
+
return null;
|
|
38238
38609
|
},
|
|
38239
38610
|
findBySlug: async ({ orgId, installationId, slug }) => {
|
|
38240
38611
|
await requireInstallation({ orgId, id: installationId });
|
|
@@ -38560,7 +38931,7 @@ var SourceControlStorage = class extends FactoryStorageDomain11 {
|
|
|
38560
38931
|
import { existsSync as existsSync2 } from "fs";
|
|
38561
38932
|
import path2, { dirname as dirname2, join as join3 } from "path";
|
|
38562
38933
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
38563
|
-
import { SandboxFilesystem } from "@mastra/code-sdk/agents/sandbox-filesystem";
|
|
38934
|
+
import { SandboxFilesystem as SandboxFilesystem2 } from "@mastra/code-sdk/agents/sandbox-filesystem";
|
|
38564
38935
|
import { MASTRACODE_WORKSPACE_TOOLS } from "@mastra/code-sdk/agents/tool-availability";
|
|
38565
38936
|
import { getDynamicWorkspace } from "@mastra/code-sdk/agents/workspace";
|
|
38566
38937
|
import { DEFAULT_CONFIG_DIR } from "@mastra/code-sdk/constants";
|
|
@@ -38746,7 +39117,7 @@ function createWorkspaceFactory(options = {}) {
|
|
|
38746
39117
|
githubTokenInjectors.set(workspaceId, { inject: injectGithubToken2, patKind, ghToken: ghCliToken });
|
|
38747
39118
|
registerGithubTokenInjector(requestContext, injectGithubToken2);
|
|
38748
39119
|
registerGithubPatKind(requestContext, patKind);
|
|
38749
|
-
const filesystem = new
|
|
39120
|
+
const filesystem = new SandboxFilesystem2({ sandbox, workdir });
|
|
38750
39121
|
const projectSkillPaths = [path2.join(configDir, "skills"), ".claude/skills", ".agents/skills"];
|
|
38751
39122
|
const skillPaths = [...effectiveSkillExtension?.paths ?? [], ...projectSkillPaths];
|
|
38752
39123
|
return new Workspace({
|