@lucern/sdk 0.2.0-alpha.4 → 0.2.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/dist/.generated +2 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -8894
- package/dist/lib/platform/auth/credentials.d.ts +5 -0
- package/dist/lib/platform/auth/credentials.js +40 -0
- package/dist/lib/platform/sdk/adminClient.d.ts +404 -0
- package/dist/lib/platform/sdk/adminClient.js +384 -0
- package/dist/lib/platform/sdk/answersClient.d.ts +16 -0
- package/dist/lib/platform/sdk/answersClient.js +21 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/audiencesClient.d.ts +6 -0
- package/dist/lib/platform/sdk/audiencesClient.js +111 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/auditClient.d.ts +3 -0
- package/dist/lib/platform/sdk/auditClient.js +21 -0
- package/dist/lib/platform/sdk/beliefsClient.d.ts +157 -0
- package/dist/lib/platform/sdk/beliefsClient.js +124 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/client.d.ts +957 -146
- package/dist/lib/platform/sdk/client.js +1831 -0
- package/dist/lib/platform/sdk/contextClient.d.ts +21 -0
- package/dist/lib/platform/sdk/contextClient.js +86 -0
- package/dist/lib/platform/sdk/contextFacade.d.ts +10 -0
- package/dist/lib/platform/sdk/contextFacade.js +10 -0
- package/dist/{lucern/packages/domain-context/src/context-pack-compiler.d.ts → lib/platform/sdk/contextPackCompiler.d.ts} +2 -3
- package/dist/lib/platform/sdk/contextPackCompiler.js +534 -0
- package/dist/lib/platform/sdk/contextTypes.d.ts +133 -0
- package/dist/lib/platform/sdk/contextTypes.js +1 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/controlObjectOwnership.d.ts +15 -0
- package/dist/lib/platform/sdk/controlObjectOwnership.js +220 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/coreClient.d.ts +19 -0
- package/dist/lib/platform/sdk/coreClient.js +366 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/customTools.d.ts +21 -3
- package/dist/lib/platform/sdk/customTools.js +247 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/decisionsClient.d.ts +9 -0
- package/dist/lib/platform/sdk/decisionsClient.js +129 -0
- package/dist/lib/platform/sdk/domainContext.d.ts +1 -0
- package/dist/lib/platform/sdk/domainContext.js +1 -0
- package/dist/lib/platform/sdk/events.d.ts +176 -0
- package/dist/lib/platform/sdk/events.js +261 -0
- package/dist/lib/platform/sdk/eventsCore.d.ts +13 -0
- package/dist/lib/platform/sdk/eventsCore.js +13 -0
- package/dist/lib/platform/sdk/gatewayFacades.d.ts +586 -0
- package/dist/lib/platform/sdk/gatewayFacades.js +845 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/graphClient.d.ts +75 -0
- package/dist/lib/platform/sdk/graphClient.js +235 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/harnessClient.d.ts +90 -1
- package/dist/lib/platform/sdk/harnessClient.js +219 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/identityClient.d.ts +45 -15
- package/dist/lib/platform/sdk/identityClient.js +131 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/index.d.ts +24 -3
- package/dist/lib/platform/sdk/index.js +49 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/learningClient.d.ts +3 -0
- package/dist/lib/platform/sdk/learningClient.js +53 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/mcpParityClient.d.ts +1 -0
- package/dist/lib/platform/sdk/mcpParityClient.js +196 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/mcpParitySurface.d.ts +2 -0
- package/dist/lib/platform/sdk/mcpParitySurface.js +57 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/ontologyClient.d.ts +16 -0
- package/dist/lib/platform/sdk/ontologyClient.js +161 -0
- package/dist/lib/platform/sdk/packRuntime.d.ts +1 -0
- package/dist/lib/platform/sdk/packRuntime.js +1 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/packsClient.d.ts +25 -0
- package/dist/lib/platform/sdk/packsClient.js +157 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/policyClient.d.ts +90 -1
- package/dist/lib/platform/sdk/policyClient.js +277 -0
- package/dist/lib/platform/sdk/promptCatalog.d.ts +1 -0
- package/dist/lib/platform/sdk/promptCatalog.js +1 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/reportsClient.d.ts +3 -0
- package/dist/lib/platform/sdk/reportsClient.js +64 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/schemaClient.d.ts +5 -0
- package/dist/lib/platform/sdk/schemaClient.js +71 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/sdkSurface.d.ts +1 -0
- package/dist/lib/platform/sdk/sdkSurface.js +140 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/topicsClient.d.ts +33 -0
- package/dist/lib/platform/sdk/topicsClient.js +118 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/types.d.ts +224 -2
- package/dist/lib/platform/sdk/types.js +1 -0
- package/dist/lib/platform/sdk/version.js +2 -0
- package/dist/{packages/sdk/src → lib/platform/sdk}/workflowClient.d.ts +63 -2
- package/dist/lib/platform/sdk/workflowClient.js +366 -0
- package/dist/lucern/contracts/src/api-enums.contract.d.ts +58 -0
- package/dist/lucern/contracts/src/api-enums.contract.js +147 -0
- package/dist/lucern/contracts/src/auth-context.contract.d.ts +8 -0
- package/dist/lucern/contracts/src/auth-context.contract.js +8 -0
- package/dist/lucern/contracts/src/auth-session.contract.d.ts +5 -50
- package/dist/lucern/contracts/src/auth-session.contract.js +8 -0
- package/dist/lucern/contracts/src/auth.contract.d.ts +88 -0
- package/dist/lucern/contracts/src/auth.contract.js +57 -0
- package/dist/lucern/contracts/src/context-pack.contract.js +169 -0
- package/dist/lucern/contracts/src/convex-admin.contract.d.ts +5 -0
- package/dist/lucern/contracts/src/convex-admin.contract.js +1 -0
- package/dist/lucern/contracts/src/events-types.contract.d.ts +8 -0
- package/dist/lucern/contracts/src/events-types.contract.js +8 -0
- package/dist/lucern/{packages/events/src/types.d.ts → contracts/src/events.contract.d.ts} +25 -0
- package/dist/lucern/contracts/src/events.contract.js +159 -0
- package/dist/lucern/contracts/src/gateway.contract.d.ts +74 -0
- package/dist/lucern/contracts/src/gateway.contract.js +19 -0
- package/dist/lucern/contracts/src/ids.contract.js +24 -0
- package/dist/lucern/contracts/src/index.d.ts +29 -0
- package/dist/lucern/contracts/src/index.js +29 -0
- package/dist/lucern/contracts/src/lens-filter.contract.js +95 -0
- package/dist/lucern/contracts/src/lens-workflow.contract.js +54 -0
- package/dist/lucern/contracts/src/mcp-tools.contract.js +3281 -0
- package/dist/lucern/contracts/src/ontology-matching.contract.d.ts +8 -0
- package/dist/lucern/contracts/src/ontology-matching.contract.js +8 -0
- package/dist/lucern/contracts/src/prompt.contract.d.ts +24 -0
- package/dist/lucern/contracts/src/prompt.contract.js +24 -0
- package/dist/lucern/contracts/src/sdk-methods.contract.d.ts +358 -0
- package/dist/lucern/contracts/src/sdk-methods.contract.js +19 -0
- package/dist/lucern/contracts/src/sdk-tools.contract.d.ts +92 -0
- package/dist/lucern/contracts/src/sdk-tools.contract.js +1398 -0
- package/dist/lucern/contracts/src/text-matching.contract.js +277 -0
- package/dist/lucern/contracts/src/topic-scope.contract.d.ts +8 -0
- package/dist/lucern/contracts/src/topic-scope.contract.js +8 -0
- package/dist/lucern/contracts/src/workflow-runtime.contract.js +257 -0
- package/dist/realtime-refs.d.ts +1 -0
- package/dist/realtime-refs.js +1 -0
- package/dist/realtime.d.ts +1 -0
- package/dist/realtime.js +1 -0
- package/package.json +18 -5
- package/dist/index.js.map +0 -1
- package/dist/lucern/mcp-server/src/context-pack-policy.d.ts +0 -119
- package/dist/lucern/mcp-server/src/context-pack-schema.d.ts +0 -18
- package/dist/lucern/modules/graph-primitives/src/ontology-matching.d.ts +0 -78
- package/dist/lucern/packages/client-core/src/beliefs.d.ts +0 -30
- package/dist/lucern/packages/client-core/src/context.d.ts +0 -29
- package/dist/lucern/packages/client-core/src/contradictions.d.ts +0 -11
- package/dist/lucern/packages/client-core/src/edges.d.ts +0 -11
- package/dist/lucern/packages/client-core/src/events.d.ts +0 -9
- package/dist/lucern/packages/client-core/src/evidence.d.ts +0 -21
- package/dist/lucern/packages/client-core/src/graph.d.ts +0 -17
- package/dist/lucern/packages/client-core/src/identity.d.ts +0 -7
- package/dist/lucern/packages/client-core/src/ontologies.d.ts +0 -13
- package/dist/lucern/packages/client-core/src/questions.d.ts +0 -39
- package/dist/lucern/packages/client-core/src/search.d.ts +0 -7
- package/dist/lucern/packages/client-core/src/tasks.d.ts +0 -13
- package/dist/lucern/packages/client-core/src/topics.d.ts +0 -17
- package/dist/lucern/packages/client-core/src/webhooks.d.ts +0 -35
- package/dist/lucern/packages/client-core/src/worktrees.d.ts +0 -17
- package/dist/lucern/packages/domain-beliefs/src/beliefs.d.ts +0 -283
- package/dist/lucern/packages/domain-beliefs/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-context/src/compile.d.ts +0 -11
- package/dist/lucern/packages/domain-context/src/index.d.ts +0 -4
- package/dist/lucern/packages/domain-context/src/ports.d.ts +0 -58
- package/dist/lucern/packages/domain-context/src/public-types.d.ts +0 -1
- package/dist/lucern/packages/domain-edges/src/contradictions.d.ts +0 -59
- package/dist/lucern/packages/domain-edges/src/edges.d.ts +0 -91
- package/dist/lucern/packages/domain-edges/src/index.d.ts +0 -2
- package/dist/lucern/packages/domain-evidence/src/evidence.d.ts +0 -115
- package/dist/lucern/packages/domain-evidence/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-graph/src/graph.d.ts +0 -150
- package/dist/lucern/packages/domain-identity/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-identity/src/whoami.d.ts +0 -13
- package/dist/lucern/packages/domain-ontologies/src/ontologies.d.ts +0 -123
- package/dist/lucern/packages/domain-questions/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-questions/src/questions.d.ts +0 -147
- package/dist/lucern/packages/domain-search/src/search.d.ts +0 -97
- package/dist/lucern/packages/domain-tasks/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-tasks/src/tasks.d.ts +0 -102
- package/dist/lucern/packages/domain-topics/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-topics/src/topics.d.ts +0 -147
- package/dist/lucern/packages/domain-worktrees/src/index.d.ts +0 -1
- package/dist/lucern/packages/domain-worktrees/src/worktrees.d.ts +0 -185
- package/dist/lucern/packages/events/src/index.d.ts +0 -4
- package/dist/lucern/packages/events/src/matching.d.ts +0 -3
- package/dist/lucern/packages/events/src/outbox.d.ts +0 -15
- package/dist/lucern/packages/events/src/webhooks.d.ts +0 -9
- package/dist/lucern/packages/sdk-typescript/src/facade/beliefs.d.ts +0 -15
- package/dist/lucern/packages/sdk-typescript/src/facade/context.d.ts +0 -12
- package/dist/lucern/packages/sdk-typescript/src/facade/contradictions.d.ts +0 -7
- package/dist/lucern/packages/sdk-typescript/src/facade/edges.d.ts +0 -7
- package/dist/lucern/packages/sdk-typescript/src/facade/events.d.ts +0 -6
- package/dist/lucern/packages/sdk-typescript/src/facade/evidence.d.ts +0 -21
- package/dist/lucern/packages/sdk-typescript/src/facade/graph.d.ts +0 -10
- package/dist/lucern/packages/sdk-typescript/src/facade/identity.d.ts +0 -5
- package/dist/lucern/packages/sdk-typescript/src/facade/ontologies.d.ts +0 -8
- package/dist/lucern/packages/sdk-typescript/src/facade/questions.d.ts +0 -39
- package/dist/lucern/packages/sdk-typescript/src/facade/search.d.ts +0 -5
- package/dist/lucern/packages/sdk-typescript/src/facade/tasks.d.ts +0 -8
- package/dist/lucern/packages/sdk-typescript/src/facade/topics.d.ts +0 -10
- package/dist/lucern/packages/sdk-typescript/src/facade/webhooks.d.ts +0 -16
- package/dist/lucern/packages/sdk-typescript/src/facade/worktrees.d.ts +0 -10
- package/dist/lucern/packages/sdk-typescript/src/index.d.ts +0 -28
- package/dist/packages/sdk/src/adminClient.d.ts +0 -89
- package/dist/packages/sdk/src/answersClient.d.ts +0 -5
- package/dist/packages/sdk/src/beliefsClient.d.ts +0 -52
- package/dist/packages/sdk/src/contextClient.d.ts +0 -9
- package/dist/packages/sdk/src/contracts/api-enums.contract.d.ts +0 -79
- /package/dist/{packages/sdk/src → lib/platform/sdk}/version.d.ts +0 -0
- /package/dist/lucern/{packages/client-core/src/ids.d.ts → contracts/src/ids.contract.d.ts} +0 -0
- /package/dist/lucern/{modules/graph-primitives/src/text-matching.d.ts → contracts/src/text-matching.contract.d.ts} +0 -0
|
@@ -3,7 +3,9 @@ import type { GetJudgmentResponse, JudgmentCalibrationResponse, JudgmentReadines
|
|
|
3
3
|
export { LucernApiError };
|
|
4
4
|
export type { PlatformGatewaySuccess } from "./coreClient";
|
|
5
5
|
export type { GetJudgmentResponse, JudgmentCalibrationResponse, JudgmentReadinessResponse, JudgmentTransitionAuditIntegrityResponse, ListJudgmentsResponse, PendingJudgmentOutcomeReviewResponse, RecordJudgmentOutcomeResponse, RecordJudgmentResponse, } from "./types";
|
|
6
|
+
/** Configuration for the decisions client. */
|
|
6
7
|
export type DecisionsClientConfig = GatewayClientConfig;
|
|
8
|
+
/** Input for recording a new judgment (irreversible decision commitment). */
|
|
7
9
|
export type RecordJudgmentInput = {
|
|
8
10
|
title: string;
|
|
9
11
|
summary?: string;
|
|
@@ -23,22 +25,27 @@ export type RecordJudgmentInput = {
|
|
|
23
25
|
terms?: string;
|
|
24
26
|
themeIds?: string[];
|
|
25
27
|
} & TopicIdentifierInput;
|
|
28
|
+
/** Filter parameters for listing judgments within a topic scope. */
|
|
26
29
|
export type ListJudgmentsInput = {
|
|
27
30
|
topicId?: string;
|
|
28
31
|
includeArchived?: boolean;
|
|
29
32
|
limit?: number;
|
|
30
33
|
} & TopicIdentifierInput;
|
|
34
|
+
/** Input for recording the real-world outcome of a judgment. */
|
|
31
35
|
export type RecordJudgmentOutcomeInput = {
|
|
32
36
|
outcome: "pending" | "successful" | "unsuccessful" | "mixed" | "unknown" | "too_early";
|
|
33
37
|
outcomeNotes?: string;
|
|
34
38
|
notes?: string;
|
|
35
39
|
};
|
|
40
|
+
/** Input for retrieving judgment calibration analytics. */
|
|
36
41
|
export type GetJudgmentCalibrationInput = {
|
|
37
42
|
topicId?: string;
|
|
38
43
|
} & TopicIdentifierInput;
|
|
44
|
+
/** Input for listing judgments still awaiting outcome review. */
|
|
39
45
|
export type ListPendingJudgmentOutcomeReviewInput = {
|
|
40
46
|
topicId?: string;
|
|
41
47
|
} & TopicIdentifierInput;
|
|
48
|
+
/** Input for checking audit integrity of judgment state transitions. */
|
|
42
49
|
export type GetJudgmentTransitionAuditIntegrityInput = {
|
|
43
50
|
topicId?: string;
|
|
44
51
|
judgmentId?: string;
|
|
@@ -46,6 +53,8 @@ export type GetJudgmentTransitionAuditIntegrityInput = {
|
|
|
46
53
|
} & TopicIdentifierInput;
|
|
47
54
|
/**
|
|
48
55
|
* Create the judgments client for decision lifecycle operations.
|
|
56
|
+
* @param config - Gateway transport configuration.
|
|
57
|
+
* @returns An object with methods to manage judgments, outcomes, readiness, and calibration.
|
|
49
58
|
*/
|
|
50
59
|
export declare function createDecisionsClient(config?: DecisionsClientConfig): {
|
|
51
60
|
/**
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { createGatewayRequestClient, LucernApiError, randomIdempotencyKey, toQueryString, } from "./coreClient.js";
|
|
2
|
+
import { createListResult, mapGatewayData, normalizeTopicQuery, withTopicAlias, } from "./sdkSurface.js";
|
|
3
|
+
export { LucernApiError };
|
|
4
|
+
/**
|
|
5
|
+
* Create the judgments client for decision lifecycle operations.
|
|
6
|
+
* @param config - Gateway transport configuration.
|
|
7
|
+
* @returns An object with methods to manage judgments, outcomes, readiness, and calibration.
|
|
8
|
+
*/
|
|
9
|
+
export function createDecisionsClient(config = {}) {
|
|
10
|
+
const gateway = createGatewayRequestClient(config);
|
|
11
|
+
return {
|
|
12
|
+
/**
|
|
13
|
+
* List judgments for a topic scope.
|
|
14
|
+
*/
|
|
15
|
+
async listJudgments(query) {
|
|
16
|
+
return gateway.request({
|
|
17
|
+
path: `/api/platform/v1/graph/judgments${toQueryString({
|
|
18
|
+
...normalizeTopicQuery(query),
|
|
19
|
+
includeArchived: typeof query.includeArchived === "boolean"
|
|
20
|
+
? query.includeArchived
|
|
21
|
+
? "true"
|
|
22
|
+
: "false"
|
|
23
|
+
: undefined,
|
|
24
|
+
limit: query.limit,
|
|
25
|
+
})}`,
|
|
26
|
+
}).then((response) => mapGatewayData(response, (data) => {
|
|
27
|
+
const rows = Array.isArray(data) ? data : [];
|
|
28
|
+
const judgments = rows.map((row) => withTopicAlias(row));
|
|
29
|
+
return {
|
|
30
|
+
...createListResult(judgments, "judgments"),
|
|
31
|
+
};
|
|
32
|
+
}));
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* Get a single judgment by identifier.
|
|
36
|
+
*/
|
|
37
|
+
async getJudgment(judgmentId) {
|
|
38
|
+
return gateway.request({
|
|
39
|
+
path: `/api/platform/v1/graph/judgments/${encodeURIComponent(judgmentId)}`,
|
|
40
|
+
}).then((response) => mapGatewayData(response, (data) => data && typeof data === "object"
|
|
41
|
+
? withTopicAlias(data)
|
|
42
|
+
: data));
|
|
43
|
+
},
|
|
44
|
+
/**
|
|
45
|
+
* Get readiness signals for creating a judgment.
|
|
46
|
+
*/
|
|
47
|
+
async getJudgmentReadiness(query) {
|
|
48
|
+
return gateway.request({
|
|
49
|
+
path: `/api/platform/v1/graph/judgments/readiness${toQueryString(normalizeTopicQuery(query))}`,
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
/**
|
|
53
|
+
* Get calibration analytics for judgment outcomes.
|
|
54
|
+
*/
|
|
55
|
+
async getJudgmentCalibration(query) {
|
|
56
|
+
return gateway.request({
|
|
57
|
+
path: `/api/platform/v1/graph/judgments/calibration${toQueryString(normalizeTopicQuery(query))}`,
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
/**
|
|
61
|
+
* List judgments still awaiting outcome review.
|
|
62
|
+
*/
|
|
63
|
+
async listPendingOutcomeReviews(query) {
|
|
64
|
+
return gateway.request({
|
|
65
|
+
path: `/api/platform/v1/graph/judgments/pending-outcome-review${toQueryString(normalizeTopicQuery(query))}`,
|
|
66
|
+
}).then((response) => mapGatewayData(response, (data) => {
|
|
67
|
+
const rows = Array.isArray(data) ? data : [];
|
|
68
|
+
const reviews = rows.map((row) => withTopicAlias(row));
|
|
69
|
+
return createListResult(reviews, "reviews");
|
|
70
|
+
}));
|
|
71
|
+
},
|
|
72
|
+
/**
|
|
73
|
+
* @deprecated Use listPendingOutcomeReviews.
|
|
74
|
+
*/
|
|
75
|
+
async listPendingJudgmentOutcomeReview(query) {
|
|
76
|
+
return this.listPendingOutcomeReviews(query);
|
|
77
|
+
},
|
|
78
|
+
/**
|
|
79
|
+
* Get audit integrity checks for judgment transitions.
|
|
80
|
+
*/
|
|
81
|
+
async getJudgmentTransitionAuditIntegrity(query) {
|
|
82
|
+
return gateway.request({
|
|
83
|
+
path: `/api/platform/v1/graph/judgments/transition-audit-integrity${toQueryString({
|
|
84
|
+
...normalizeTopicQuery(query),
|
|
85
|
+
judgmentId: query.judgmentId,
|
|
86
|
+
includePassing: typeof query.includePassing === "boolean"
|
|
87
|
+
? query.includePassing
|
|
88
|
+
? "true"
|
|
89
|
+
: "false"
|
|
90
|
+
: undefined,
|
|
91
|
+
})}`,
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
/**
|
|
95
|
+
* Create a judgment.
|
|
96
|
+
*/
|
|
97
|
+
async createJudgment(input, idempotencyKey) {
|
|
98
|
+
return gateway.request({
|
|
99
|
+
path: "/api/platform/v1/graph/judgments",
|
|
100
|
+
method: "POST",
|
|
101
|
+
body: normalizeTopicQuery(input),
|
|
102
|
+
idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
|
|
103
|
+
}).then((response) => mapGatewayData(response, (data) => withTopicAlias(data)));
|
|
104
|
+
},
|
|
105
|
+
/**
|
|
106
|
+
* @deprecated Use createJudgment.
|
|
107
|
+
*/
|
|
108
|
+
async recordJudgment(input, idempotencyKey) {
|
|
109
|
+
return this.createJudgment(input, idempotencyKey);
|
|
110
|
+
},
|
|
111
|
+
/**
|
|
112
|
+
* Update the outcome for an existing judgment.
|
|
113
|
+
*/
|
|
114
|
+
async updateJudgmentOutcome(judgmentId, input, idempotencyKey) {
|
|
115
|
+
return gateway.request({
|
|
116
|
+
path: `/api/platform/v1/graph/judgments/${encodeURIComponent(judgmentId)}/outcome`,
|
|
117
|
+
method: "POST",
|
|
118
|
+
body: input,
|
|
119
|
+
idempotencyKey: idempotencyKey ?? randomIdempotencyKey(),
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
/**
|
|
123
|
+
* @deprecated Use updateJudgmentOutcome.
|
|
124
|
+
*/
|
|
125
|
+
async recordJudgmentOutcome(judgmentId, input, idempotencyKey) {
|
|
126
|
+
return this.updateJudgmentOutcome(judgmentId, input, idempotencyKey);
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { CompileContextInput, ContextCompilationMode, ContextPackSectionKey, ContextRankingProfile, PackWeightOverride, PublicCompiledContext, PublicContextBelief, PublicContextContradiction, PublicContextEntity, PublicContextEvidence, PublicContextInjectionPolicy, PublicContextQuestion, RankingWeightVector, } from "./contextTypes";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
export declare const DOMAIN_EVENT_VERSION: "1.0";
|
|
2
|
+
export declare const EVENT_RETENTION_DEFAULT_DAYS = 30;
|
|
3
|
+
export declare const WEBHOOK_MAX_ATTEMPTS = 5;
|
|
4
|
+
export declare const WEBHOOK_RETRY_DELAYS_MS: readonly [1000, 5000, 30000, 300000];
|
|
5
|
+
export declare const DOMAIN_EVENT_TYPES: readonly ["belief.created", "belief.forked", "belief.confidence_updated", "belief.archived", "belief.refined", "belief.contract_created", "belief.contract_evaluated", "belief.lineage_queried", "evidence.created", "evidence.linked", "evidence.search_executed", "question.created", "question.answered", "question.refined", "question.status_updated", "question.archived", "edge.created", "contradiction.flagged", "worktree.created", "worktree.activated", "worktree.merged", "worktree.targets_updated", "worktree.metadata_updated", "topic.created", "topic.updated", "topic.archived", "task.created", "task.completed", "task.updated", "ontology.bound", "context.compiled", "identity.key_created", "identity.key_rotated", "identity.key_revoked", "webhook.test"];
|
|
6
|
+
export type DomainEventType = (typeof DOMAIN_EVENT_TYPES)[number];
|
|
7
|
+
export type DomainResourceType = "belief" | "evidence" | "question" | "edge" | "contradiction" | "worktree" | "topic" | "task" | "ontology" | "context" | "identity" | "webhook";
|
|
8
|
+
export type DomainActorType = "human" | "agent" | "service";
|
|
9
|
+
export type DomainEventData = Record<string, unknown>;
|
|
10
|
+
export type DomainEvent = {
|
|
11
|
+
eventId: string;
|
|
12
|
+
type: DomainEventType | string;
|
|
13
|
+
version: typeof DOMAIN_EVENT_VERSION;
|
|
14
|
+
timestamp: number;
|
|
15
|
+
tenantId?: string;
|
|
16
|
+
workspaceId?: string;
|
|
17
|
+
topicId: string;
|
|
18
|
+
resourceId: string;
|
|
19
|
+
resourceType: DomainResourceType | string;
|
|
20
|
+
actorId: string;
|
|
21
|
+
actorType: DomainActorType;
|
|
22
|
+
data: DomainEventData;
|
|
23
|
+
correlationId?: string;
|
|
24
|
+
expiresAt: number;
|
|
25
|
+
};
|
|
26
|
+
export type CreateDomainEventInput = {
|
|
27
|
+
eventId?: string;
|
|
28
|
+
timestamp?: number;
|
|
29
|
+
tenantId?: string;
|
|
30
|
+
workspaceId?: string;
|
|
31
|
+
topicId: string;
|
|
32
|
+
type: DomainEventType | string;
|
|
33
|
+
resourceId: string;
|
|
34
|
+
resourceType: DomainResourceType | string;
|
|
35
|
+
actorId: string;
|
|
36
|
+
actorType: DomainActorType;
|
|
37
|
+
data?: DomainEventData;
|
|
38
|
+
correlationId?: string;
|
|
39
|
+
retentionDays?: number;
|
|
40
|
+
};
|
|
41
|
+
export type EventCursor = {
|
|
42
|
+
timestamp: number;
|
|
43
|
+
eventId: string;
|
|
44
|
+
};
|
|
45
|
+
export type EventListQuery = {
|
|
46
|
+
topicId?: string;
|
|
47
|
+
after?: string;
|
|
48
|
+
types?: string[];
|
|
49
|
+
startTime?: number;
|
|
50
|
+
endTime?: number;
|
|
51
|
+
limit?: number;
|
|
52
|
+
};
|
|
53
|
+
export type EventListResult = {
|
|
54
|
+
events: DomainEvent[];
|
|
55
|
+
nextCursor: string | null;
|
|
56
|
+
};
|
|
57
|
+
export type WebhookSecretMode = "configured";
|
|
58
|
+
export type WebhookRecord = {
|
|
59
|
+
id: string;
|
|
60
|
+
webhookId: string;
|
|
61
|
+
tenantId?: string;
|
|
62
|
+
workspaceId?: string;
|
|
63
|
+
topicId?: string;
|
|
64
|
+
url: string;
|
|
65
|
+
events: string[];
|
|
66
|
+
active: boolean;
|
|
67
|
+
secretConfigured: boolean;
|
|
68
|
+
createdAt: number;
|
|
69
|
+
updatedAt: number;
|
|
70
|
+
createdBy: string;
|
|
71
|
+
updatedBy: string;
|
|
72
|
+
lastDeliveryAt?: number;
|
|
73
|
+
lastSuccessfulDeliveryAt?: number;
|
|
74
|
+
};
|
|
75
|
+
export type WebhookCreateInput = {
|
|
76
|
+
url: string;
|
|
77
|
+
events: string[];
|
|
78
|
+
secret: string;
|
|
79
|
+
topicId?: string;
|
|
80
|
+
active?: boolean;
|
|
81
|
+
};
|
|
82
|
+
export type WebhookUpdateInput = {
|
|
83
|
+
url?: string;
|
|
84
|
+
events?: string[];
|
|
85
|
+
secret?: string;
|
|
86
|
+
topicId?: string | null;
|
|
87
|
+
active?: boolean;
|
|
88
|
+
};
|
|
89
|
+
export type WebhookDeliveryStatus = "pending" | "delivering" | "succeeded" | "failed" | "dead_letter";
|
|
90
|
+
export type WebhookDeliveryRecord = {
|
|
91
|
+
id: string;
|
|
92
|
+
deliveryId: string;
|
|
93
|
+
webhookId: string;
|
|
94
|
+
eventId: string;
|
|
95
|
+
eventType: string;
|
|
96
|
+
topicId: string;
|
|
97
|
+
status: WebhookDeliveryStatus;
|
|
98
|
+
attemptCount: number;
|
|
99
|
+
maxAttempts: number;
|
|
100
|
+
nextAttemptAt?: number;
|
|
101
|
+
lastAttemptAt?: number;
|
|
102
|
+
lastStatusCode?: number;
|
|
103
|
+
lastError?: string;
|
|
104
|
+
deliveredAt?: number;
|
|
105
|
+
createdAt: number;
|
|
106
|
+
updatedAt: number;
|
|
107
|
+
};
|
|
108
|
+
export type WebhookDeliveryAttemptRecord = {
|
|
109
|
+
id: string;
|
|
110
|
+
attemptId: string;
|
|
111
|
+
deliveryId: string;
|
|
112
|
+
webhookId: string;
|
|
113
|
+
eventId: string;
|
|
114
|
+
eventType: string;
|
|
115
|
+
attemptNumber: number;
|
|
116
|
+
status: "succeeded" | "failed";
|
|
117
|
+
statusCode?: number;
|
|
118
|
+
error?: string;
|
|
119
|
+
responseBody?: string;
|
|
120
|
+
durationMs?: number;
|
|
121
|
+
createdAt: number;
|
|
122
|
+
};
|
|
123
|
+
export type WebhookDeliveriesResult = {
|
|
124
|
+
deliveries: Array<WebhookDeliveryRecord & {
|
|
125
|
+
attempts?: WebhookDeliveryAttemptRecord[];
|
|
126
|
+
}>;
|
|
127
|
+
};
|
|
128
|
+
export type WebhookHealthResult = {
|
|
129
|
+
webhookId: string;
|
|
130
|
+
totalAttempts: number;
|
|
131
|
+
successfulAttempts: number;
|
|
132
|
+
failedAttempts: number;
|
|
133
|
+
successRate: number;
|
|
134
|
+
pendingDeliveries: number;
|
|
135
|
+
deadLetterDeliveries: number;
|
|
136
|
+
lastDeliveryAt?: number;
|
|
137
|
+
lastSuccessfulDeliveryAt?: number;
|
|
138
|
+
};
|
|
139
|
+
export type WebhookTestResult = {
|
|
140
|
+
webhookId: string;
|
|
141
|
+
deliveryId: string;
|
|
142
|
+
status: WebhookDeliveryStatus;
|
|
143
|
+
attempts: number;
|
|
144
|
+
};
|
|
145
|
+
export type ReplayEventsInput = EventListQuery & {
|
|
146
|
+
webhookId?: string;
|
|
147
|
+
};
|
|
148
|
+
export type ReplayEventsResult = EventListResult & {
|
|
149
|
+
replayedDeliveries?: number;
|
|
150
|
+
replayedWebhookId?: string;
|
|
151
|
+
};
|
|
152
|
+
export declare function eventPatternToRegExp(pattern: string): RegExp;
|
|
153
|
+
export declare function matchesEventPattern(eventType: string, pattern: string): boolean;
|
|
154
|
+
export declare function matchesAnyEventPattern(eventType: string, patterns: readonly string[]): boolean;
|
|
155
|
+
export declare function createEventId(): string;
|
|
156
|
+
export declare function normalizeRetentionDays(value: number | undefined): number;
|
|
157
|
+
export declare function buildDomainEvent(input: CreateDomainEventInput): DomainEvent;
|
|
158
|
+
export declare function compareEventCursor(left: EventCursor, right: EventCursor): number;
|
|
159
|
+
export declare function encodeEventCursor(cursor: EventCursor): string;
|
|
160
|
+
export declare function decodeEventCursor(cursor: string | undefined): EventCursor | null;
|
|
161
|
+
export declare function isAfterCursor(event: Pick<DomainEvent, "timestamp" | "eventId">, cursor: EventCursor | null): boolean;
|
|
162
|
+
export declare function sortEventsByCursor<T extends Pick<DomainEvent, "timestamp" | "eventId">>(events: readonly T[]): T[];
|
|
163
|
+
export declare function inferActorType(args: {
|
|
164
|
+
sessionType?: "agent" | "user";
|
|
165
|
+
authMode?: string;
|
|
166
|
+
principalType?: string;
|
|
167
|
+
}): DomainActorType;
|
|
168
|
+
export declare function emitDomainEvent(invokeMutation: (reference: any, args: CreateDomainEventInput) => Promise<unknown>, input: CreateDomainEventInput): Promise<unknown>;
|
|
169
|
+
export declare function assertValidWebhookUrl(url: string): string;
|
|
170
|
+
export declare function normalizeWebhookPatterns(patterns: readonly string[]): string[];
|
|
171
|
+
export declare function assertValidWebhookSecret(secret: string): string;
|
|
172
|
+
export declare function computeWebhookSignature(payload: string, secret: string): Promise<string>;
|
|
173
|
+
export declare function nextDeliveryAttemptAt(currentAttemptCount: number, now?: number): number | undefined;
|
|
174
|
+
export declare function resolveDeliveryFailureStatus(attemptCount: number): WebhookDeliveryStatus;
|
|
175
|
+
export declare function sanitizeWebhookRecord(value: Record<string, unknown>): WebhookRecord;
|
|
176
|
+
export declare function truncateWebhookResponseBody(responseBody: string | undefined, maxLength?: number): string | undefined;
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
export const DOMAIN_EVENT_VERSION = "1.0";
|
|
2
|
+
export const EVENT_RETENTION_DEFAULT_DAYS = 30;
|
|
3
|
+
export const WEBHOOK_MAX_ATTEMPTS = 5;
|
|
4
|
+
export const WEBHOOK_RETRY_DELAYS_MS = [1_000, 5_000, 30_000, 300_000];
|
|
5
|
+
export const DOMAIN_EVENT_TYPES = [
|
|
6
|
+
"belief.created",
|
|
7
|
+
"belief.forked",
|
|
8
|
+
"belief.confidence_updated",
|
|
9
|
+
"belief.archived",
|
|
10
|
+
"belief.refined",
|
|
11
|
+
"belief.contract_created",
|
|
12
|
+
"belief.contract_evaluated",
|
|
13
|
+
"belief.lineage_queried",
|
|
14
|
+
"evidence.created",
|
|
15
|
+
"evidence.linked",
|
|
16
|
+
"evidence.search_executed",
|
|
17
|
+
"question.created",
|
|
18
|
+
"question.answered",
|
|
19
|
+
"question.refined",
|
|
20
|
+
"question.status_updated",
|
|
21
|
+
"question.archived",
|
|
22
|
+
"edge.created",
|
|
23
|
+
"contradiction.flagged",
|
|
24
|
+
"worktree.created",
|
|
25
|
+
"worktree.activated",
|
|
26
|
+
"worktree.merged",
|
|
27
|
+
"worktree.targets_updated",
|
|
28
|
+
"worktree.metadata_updated",
|
|
29
|
+
"topic.created",
|
|
30
|
+
"topic.updated",
|
|
31
|
+
"topic.archived",
|
|
32
|
+
"task.created",
|
|
33
|
+
"task.completed",
|
|
34
|
+
"task.updated",
|
|
35
|
+
"ontology.bound",
|
|
36
|
+
"context.compiled",
|
|
37
|
+
"identity.key_created",
|
|
38
|
+
"identity.key_rotated",
|
|
39
|
+
"identity.key_revoked",
|
|
40
|
+
"webhook.test",
|
|
41
|
+
];
|
|
42
|
+
function escapeRegex(value) {
|
|
43
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
44
|
+
}
|
|
45
|
+
export function eventPatternToRegExp(pattern) {
|
|
46
|
+
const normalized = pattern.trim();
|
|
47
|
+
if (!normalized) {
|
|
48
|
+
return /^$/;
|
|
49
|
+
}
|
|
50
|
+
if (normalized === "*") {
|
|
51
|
+
return /^.*$/;
|
|
52
|
+
}
|
|
53
|
+
const source = escapeRegex(normalized).replace(/\\\*/g, ".*");
|
|
54
|
+
return new RegExp(`^${source}$`);
|
|
55
|
+
}
|
|
56
|
+
export function matchesEventPattern(eventType, pattern) {
|
|
57
|
+
return eventPatternToRegExp(pattern).test(eventType.trim());
|
|
58
|
+
}
|
|
59
|
+
export function matchesAnyEventPattern(eventType, patterns) {
|
|
60
|
+
if (patterns.length === 0) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
return patterns.some((pattern) => matchesEventPattern(eventType, pattern));
|
|
64
|
+
}
|
|
65
|
+
function toBase64(value) {
|
|
66
|
+
if (typeof Buffer !== "undefined") {
|
|
67
|
+
return Buffer.from(value, "utf8").toString("base64url");
|
|
68
|
+
}
|
|
69
|
+
return btoa(unescape(encodeURIComponent(value)))
|
|
70
|
+
.replace(/\+/g, "-")
|
|
71
|
+
.replace(/\//g, "_")
|
|
72
|
+
.replace(/=+$/g, "");
|
|
73
|
+
}
|
|
74
|
+
function fromBase64(value) {
|
|
75
|
+
if (typeof Buffer !== "undefined") {
|
|
76
|
+
return Buffer.from(value, "base64url").toString("utf8");
|
|
77
|
+
}
|
|
78
|
+
const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
79
|
+
return decodeURIComponent(escape(atob(normalized)));
|
|
80
|
+
}
|
|
81
|
+
export function createEventId() {
|
|
82
|
+
const random = typeof globalThis.crypto?.randomUUID === "function"
|
|
83
|
+
? globalThis.crypto.randomUUID().replace(/-/g, "")
|
|
84
|
+
: Array.from(typeof globalThis.crypto?.getRandomValues === "function"
|
|
85
|
+
? globalThis.crypto.getRandomValues(new Uint8Array(16))
|
|
86
|
+
: Array.from({ length: 16 }, () => Math.floor(Math.random() * 256)), (value) => value.toString(16).padStart(2, "0")).join("");
|
|
87
|
+
return `evt_${random}`;
|
|
88
|
+
}
|
|
89
|
+
export function normalizeRetentionDays(value) {
|
|
90
|
+
if (!Number.isFinite(value) || typeof value !== "number" || value <= 0) {
|
|
91
|
+
return EVENT_RETENTION_DEFAULT_DAYS;
|
|
92
|
+
}
|
|
93
|
+
return Math.max(1, Math.trunc(value));
|
|
94
|
+
}
|
|
95
|
+
export function buildDomainEvent(input) {
|
|
96
|
+
const timestamp = input.timestamp ?? Date.now();
|
|
97
|
+
const retentionDays = normalizeRetentionDays(input.retentionDays);
|
|
98
|
+
return {
|
|
99
|
+
eventId: input.eventId?.trim() || createEventId(),
|
|
100
|
+
type: input.type.trim(),
|
|
101
|
+
version: DOMAIN_EVENT_VERSION,
|
|
102
|
+
timestamp,
|
|
103
|
+
tenantId: input.tenantId?.trim() || undefined,
|
|
104
|
+
workspaceId: input.workspaceId?.trim() || undefined,
|
|
105
|
+
topicId: input.topicId.trim(),
|
|
106
|
+
resourceId: input.resourceId.trim(),
|
|
107
|
+
resourceType: input.resourceType.trim(),
|
|
108
|
+
actorId: input.actorId.trim(),
|
|
109
|
+
actorType: input.actorType,
|
|
110
|
+
data: input.data ?? {},
|
|
111
|
+
correlationId: input.correlationId?.trim() || undefined,
|
|
112
|
+
expiresAt: timestamp + retentionDays * 24 * 60 * 60 * 1000,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export function compareEventCursor(left, right) {
|
|
116
|
+
if (left.timestamp !== right.timestamp) {
|
|
117
|
+
return left.timestamp - right.timestamp;
|
|
118
|
+
}
|
|
119
|
+
return left.eventId.localeCompare(right.eventId);
|
|
120
|
+
}
|
|
121
|
+
export function encodeEventCursor(cursor) {
|
|
122
|
+
return toBase64(JSON.stringify(cursor));
|
|
123
|
+
}
|
|
124
|
+
export function decodeEventCursor(cursor) {
|
|
125
|
+
if (!cursor || cursor.trim().length === 0) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const parsed = JSON.parse(fromBase64(cursor.trim()));
|
|
130
|
+
if (typeof parsed.timestamp !== "number" ||
|
|
131
|
+
!Number.isFinite(parsed.timestamp) ||
|
|
132
|
+
typeof parsed.eventId !== "string" ||
|
|
133
|
+
parsed.eventId.trim().length === 0) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
timestamp: parsed.timestamp,
|
|
138
|
+
eventId: parsed.eventId.trim(),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
export function isAfterCursor(event, cursor) {
|
|
146
|
+
if (!cursor) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
return compareEventCursor(event, cursor) > 0;
|
|
150
|
+
}
|
|
151
|
+
export function sortEventsByCursor(events) {
|
|
152
|
+
return [...events].sort((left, right) => compareEventCursor(left, right));
|
|
153
|
+
}
|
|
154
|
+
export function inferActorType(args) {
|
|
155
|
+
if (args.sessionType === "agent") {
|
|
156
|
+
return "agent";
|
|
157
|
+
}
|
|
158
|
+
if (args.authMode === "service_principal" ||
|
|
159
|
+
args.authMode === "tenant_api_key" ||
|
|
160
|
+
args.principalType === "service") {
|
|
161
|
+
return "service";
|
|
162
|
+
}
|
|
163
|
+
return "human";
|
|
164
|
+
}
|
|
165
|
+
export async function emitDomainEvent(invokeMutation, input) {
|
|
166
|
+
return await invokeMutation("events:recordEvent", input);
|
|
167
|
+
}
|
|
168
|
+
const LOCALHOST_HOSTS = new Set(["localhost", "127.0.0.1", "::1"]);
|
|
169
|
+
function normalizeUrl(url) {
|
|
170
|
+
try {
|
|
171
|
+
return new URL(url.trim());
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
throw new Error("Webhook URL must be a valid absolute URL.");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
export function assertValidWebhookUrl(url) {
|
|
178
|
+
const parsed = normalizeUrl(url);
|
|
179
|
+
const hostname = parsed.hostname.trim().toLowerCase();
|
|
180
|
+
const nodeEnv = typeof process !== "undefined" ? process.env?.NODE_ENV : undefined;
|
|
181
|
+
const allowLocalHttp = nodeEnv === "test" || LOCALHOST_HOSTS.has(hostname);
|
|
182
|
+
if (parsed.protocol !== "https:" && !(allowLocalHttp && parsed.protocol === "http:")) {
|
|
183
|
+
throw new Error("Webhook URL must use HTTPS.");
|
|
184
|
+
}
|
|
185
|
+
return parsed.toString();
|
|
186
|
+
}
|
|
187
|
+
export function normalizeWebhookPatterns(patterns) {
|
|
188
|
+
const normalized = Array.from(new Set(patterns
|
|
189
|
+
.map((pattern) => pattern.trim())
|
|
190
|
+
.filter((pattern) => pattern.length > 0)));
|
|
191
|
+
if (normalized.length === 0) {
|
|
192
|
+
throw new Error("At least one webhook event pattern is required.");
|
|
193
|
+
}
|
|
194
|
+
return normalized;
|
|
195
|
+
}
|
|
196
|
+
export function assertValidWebhookSecret(secret) {
|
|
197
|
+
const normalized = secret.trim();
|
|
198
|
+
if (normalized.length < 8) {
|
|
199
|
+
throw new Error("Webhook secret must be at least 8 characters.");
|
|
200
|
+
}
|
|
201
|
+
return normalized;
|
|
202
|
+
}
|
|
203
|
+
export async function computeWebhookSignature(payload, secret) {
|
|
204
|
+
const encoder = new TextEncoder();
|
|
205
|
+
const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
206
|
+
const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(payload));
|
|
207
|
+
return Array.from(new Uint8Array(signature))
|
|
208
|
+
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
209
|
+
.join("");
|
|
210
|
+
}
|
|
211
|
+
export function nextDeliveryAttemptAt(currentAttemptCount, now = Date.now()) {
|
|
212
|
+
if (currentAttemptCount >= WEBHOOK_MAX_ATTEMPTS) {
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
const retryIndex = currentAttemptCount - 1;
|
|
216
|
+
const delay = WEBHOOK_RETRY_DELAYS_MS[retryIndex];
|
|
217
|
+
return typeof delay === "number" ? now + delay : undefined;
|
|
218
|
+
}
|
|
219
|
+
export function resolveDeliveryFailureStatus(attemptCount) {
|
|
220
|
+
return attemptCount >= WEBHOOK_MAX_ATTEMPTS ? "dead_letter" : "failed";
|
|
221
|
+
}
|
|
222
|
+
export function sanitizeWebhookRecord(value) {
|
|
223
|
+
return {
|
|
224
|
+
id: String(value.id ?? value.webhookId ?? value._id ?? ""),
|
|
225
|
+
webhookId: String(value.webhookId ?? value.id ?? value._id ?? ""),
|
|
226
|
+
tenantId: typeof value.tenantId === "string" && value.tenantId.trim().length > 0
|
|
227
|
+
? value.tenantId
|
|
228
|
+
: undefined,
|
|
229
|
+
workspaceId: typeof value.workspaceId === "string" && value.workspaceId.trim().length > 0
|
|
230
|
+
? value.workspaceId
|
|
231
|
+
: undefined,
|
|
232
|
+
topicId: typeof value.topicId === "string" && value.topicId.trim().length > 0
|
|
233
|
+
? value.topicId
|
|
234
|
+
: undefined,
|
|
235
|
+
url: String(value.url ?? ""),
|
|
236
|
+
events: Array.isArray(value.events)
|
|
237
|
+
? value.events
|
|
238
|
+
.map((entry) => (typeof entry === "string" ? entry.trim() : ""))
|
|
239
|
+
.filter(Boolean)
|
|
240
|
+
: [],
|
|
241
|
+
active: value.active !== false,
|
|
242
|
+
secretConfigured: true,
|
|
243
|
+
createdAt: Number(value.createdAt ?? Date.now()),
|
|
244
|
+
updatedAt: Number(value.updatedAt ?? value.createdAt ?? Date.now()),
|
|
245
|
+
createdBy: String(value.createdBy ?? ""),
|
|
246
|
+
updatedBy: String(value.updatedBy ?? value.createdBy ?? ""),
|
|
247
|
+
lastDeliveryAt: typeof value.lastDeliveryAt === "number" ? value.lastDeliveryAt : undefined,
|
|
248
|
+
lastSuccessfulDeliveryAt: typeof value.lastSuccessfulDeliveryAt === "number"
|
|
249
|
+
? value.lastSuccessfulDeliveryAt
|
|
250
|
+
: undefined,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
export function truncateWebhookResponseBody(responseBody, maxLength = 2_000) {
|
|
254
|
+
if (!responseBody) {
|
|
255
|
+
return undefined;
|
|
256
|
+
}
|
|
257
|
+
if (responseBody.length <= maxLength) {
|
|
258
|
+
return responseBody;
|
|
259
|
+
}
|
|
260
|
+
return `${responseBody.slice(0, maxLength - 3)}...`;
|
|
261
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal events/webhooks client factories exposed for testing / audit.
|
|
3
|
+
*
|
|
4
|
+
* These core factories live in `@lucern/client-core` and are bundled
|
|
5
|
+
* into `@lucern/sdk` at build time via the tsup alias map. Re-exported
|
|
6
|
+
* here so downstream test/audit tooling can import them from the
|
|
7
|
+
* public `@lucern/sdk` entry point instead of reaching into the
|
|
8
|
+
* package internals directly.
|
|
9
|
+
*
|
|
10
|
+
* Added: EK-16 T7.3.4 (2026-04-18).
|
|
11
|
+
*/
|
|
12
|
+
export { createEventsClientCore, type EventsClientCoreConfig, } from "@/lucern/packages/client-core/src/events";
|
|
13
|
+
export { createWebhooksClientCore, type WebhooksClientCoreConfig, } from "@/lucern/packages/client-core/src/webhooks";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal events/webhooks client factories exposed for testing / audit.
|
|
3
|
+
*
|
|
4
|
+
* These core factories live in `@lucern/client-core` and are bundled
|
|
5
|
+
* into `@lucern/sdk` at build time via the tsup alias map. Re-exported
|
|
6
|
+
* here so downstream test/audit tooling can import them from the
|
|
7
|
+
* public `@lucern/sdk` entry point instead of reaching into the
|
|
8
|
+
* package internals directly.
|
|
9
|
+
*
|
|
10
|
+
* Added: EK-16 T7.3.4 (2026-04-18).
|
|
11
|
+
*/
|
|
12
|
+
export { createEventsClientCore, } from "@/lucern/packages/client-core/src/events";
|
|
13
|
+
export { createWebhooksClientCore, } from "@/lucern/packages/client-core/src/webhooks";
|