@lota-sdk/core 0.1.18 → 0.1.20
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/infrastructure/schema/09_queue_job.surql +38 -0
- package/infrastructure/schema/10_autonomous_job.surql +44 -0
- package/package.json +2 -2
- package/src/ai-gateway/ai-gateway.ts +130 -21
- package/src/ai-gateway/cache-headers.ts +26 -1
- package/src/create-runtime.ts +10 -1
- package/src/db/base.service.ts +6 -1
- package/src/db/tables.ts +4 -0
- package/src/queues/autonomous-job.queue.ts +134 -0
- package/src/queues/document-processor.queue.ts +13 -2
- package/src/queues/index.ts +1 -0
- package/src/queues/memory-consolidation.queue.ts +22 -3
- package/src/queues/queue-factory.ts +33 -4
- package/src/runtime/chat-run-registry.ts +4 -0
- package/src/runtime/context-compaction.ts +100 -12
- package/src/runtime/memory-prompts-fact.ts +3 -1
- package/src/runtime/runtime-config.ts +1 -1
- package/src/runtime/runtime-worker-registry.ts +3 -0
- package/src/services/autonomous-job.service.ts +692 -0
- package/src/services/index.ts +2 -0
- package/src/services/plan-deadline.service.ts +6 -4
- package/src/services/queue-job.service.ts +356 -0
- package/src/services/workstream-message.service.ts +25 -14
- package/src/services/workstream-title.service.ts +1 -1
- package/src/services/workstream-turn-preparation.service.ts +22 -6
- package/src/services/workstream-turn.ts +11 -3
- package/src/services/workstream.service.ts +19 -2
- package/src/system-agents/context-compaction.agent.ts +2 -2
- package/src/system-agents/delegated-agent-factory.ts +2 -9
- package/src/system-agents/memory-reranker.agent.ts +2 -2
- package/src/system-agents/memory.agent.ts +2 -2
- package/src/system-agents/recent-activity-title-refiner.agent.ts +2 -2
- package/src/system-agents/regular-chat-memory-digest.agent.ts +2 -2
- package/src/system-agents/skill-extractor.agent.ts +2 -2
- package/src/system-agents/skill-manager.agent.ts +2 -2
- package/src/system-agents/title-generator.agent.ts +2 -2
- package/src/tools/research-topic.tool.ts +2 -2
- package/src/utils/date-time.ts +11 -0
- package/src/workers/utils/file-section-chunker.ts +1 -1
- package/src/workers/worker-utils.ts +35 -7
|
@@ -525,6 +525,22 @@ class WorkstreamService extends BaseService<typeof WorkstreamSchema> {
|
|
|
525
525
|
)
|
|
526
526
|
}
|
|
527
527
|
|
|
528
|
+
async clearStaleActiveRunIfMissingFromRegistry(workstreamId: RecordIdRef): Promise<boolean> {
|
|
529
|
+
const activeRunId = await this.getActiveRunId(workstreamId)
|
|
530
|
+
if (!activeRunId || chatRunRegistry.has(activeRunId)) {
|
|
531
|
+
return false
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
const activeStreamId = await this.getActiveStreamId(workstreamId)
|
|
535
|
+
await Promise.all([
|
|
536
|
+
this.clearActiveRunIdIfMatches(workstreamId, activeRunId),
|
|
537
|
+
activeStreamId ? this.clearActiveStreamIdIfMatches(workstreamId, activeStreamId) : Promise.resolve(),
|
|
538
|
+
])
|
|
539
|
+
|
|
540
|
+
serverLogger.warn`Cleared stale workstream run after process restart: workstream=${recordIdToString(ensureRecordId(workstreamId, TABLES.WORKSTREAM), TABLES.WORKSTREAM)} run=${activeRunId}`
|
|
541
|
+
return true
|
|
542
|
+
}
|
|
543
|
+
|
|
528
544
|
async stopActiveRun(workstreamId: RecordIdRef): Promise<boolean> {
|
|
529
545
|
const activeRunId = await this.getActiveRunId(workstreamId)
|
|
530
546
|
if (!activeRunId) return false
|
|
@@ -534,7 +550,7 @@ class WorkstreamService extends BaseService<typeof WorkstreamSchema> {
|
|
|
534
550
|
return true
|
|
535
551
|
}
|
|
536
552
|
|
|
537
|
-
await this.
|
|
553
|
+
await this.clearStaleActiveRunIfMissingFromRegistry(workstreamId)
|
|
538
554
|
return false
|
|
539
555
|
}
|
|
540
556
|
|
|
@@ -675,6 +691,7 @@ class WorkstreamService extends BaseService<typeof WorkstreamSchema> {
|
|
|
675
691
|
typeof workstream.activeRunId === 'string' && workstream.activeRunId.trim().length > 0
|
|
676
692
|
? workstream.activeRunId
|
|
677
693
|
: null
|
|
694
|
+
const isRunning = activeRunId !== null && chatRunRegistry.has(activeRunId)
|
|
678
695
|
const isCompacting = workstream.isCompacting === true
|
|
679
696
|
const mode = workstream.mode
|
|
680
697
|
const core = workstream.core
|
|
@@ -688,7 +705,7 @@ class WorkstreamService extends BaseService<typeof WorkstreamSchema> {
|
|
|
688
705
|
core,
|
|
689
706
|
...(coreType ? { coreType } : {}),
|
|
690
707
|
nameGenerated: workstream.nameGenerated,
|
|
691
|
-
isRunning
|
|
708
|
+
isRunning,
|
|
692
709
|
isCompacting,
|
|
693
710
|
...(isAgentName(workstream.agentId) ? { agentId: workstream.agentId } : {}),
|
|
694
711
|
title: workstream.title ?? this.getDefaultTitle(workstream),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ToolLoopAgent } from 'ai'
|
|
2
2
|
|
|
3
3
|
import { aiGatewayOpenRouterResponseHealingModel } from '../ai-gateway/ai-gateway'
|
|
4
|
-
import {
|
|
4
|
+
import { buildAiGatewayDirectCacheHeaders } from '../ai-gateway/cache-headers'
|
|
5
5
|
import {
|
|
6
6
|
OPENROUTER_STRUCTURED_HELPER_MODEL_ID,
|
|
7
7
|
OPENROUTER_HIGH_REASONING_PROVIDER_OPTIONS,
|
|
@@ -41,7 +41,7 @@ export function createContextCompactionAgent(options: CreateHelperToolLoopAgentO
|
|
|
41
41
|
return new ToolLoopAgent({
|
|
42
42
|
id: 'context-compaction',
|
|
43
43
|
model: aiGatewayOpenRouterResponseHealingModel(OPENROUTER_STRUCTURED_HELPER_MODEL_ID),
|
|
44
|
-
headers:
|
|
44
|
+
headers: buildAiGatewayDirectCacheHeaders('context-compaction'),
|
|
45
45
|
providerOptions: OPENROUTER_HIGH_REASONING_PROVIDER_OPTIONS,
|
|
46
46
|
...resolveHelperAgentOptions(options, { instructions: CONTEXT_COMPACTION_PROMPT }),
|
|
47
47
|
})
|
|
@@ -4,6 +4,7 @@ import { z } from 'zod'
|
|
|
4
4
|
|
|
5
5
|
import type { ToolDefinition } from '../ai/definitions'
|
|
6
6
|
import { aiLogger } from '../config/logger'
|
|
7
|
+
import { formatUtcPromptDate } from '../utils/date-time'
|
|
7
8
|
import { isRecord } from '../utils/string'
|
|
8
9
|
import { assertSubstantiveAgentResult } from './agent-result'
|
|
9
10
|
|
|
@@ -32,15 +33,7 @@ function resolveAgentModel(model: AgentModel): LanguageModel {
|
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
function buildCurrentDateContext(now = new Date()): string {
|
|
35
|
-
|
|
36
|
-
const humanDate = new Intl.DateTimeFormat('en-US', {
|
|
37
|
-
timeZone: 'UTC',
|
|
38
|
-
year: 'numeric',
|
|
39
|
-
month: 'long',
|
|
40
|
-
day: 'numeric',
|
|
41
|
-
}).format(now)
|
|
42
|
-
|
|
43
|
-
return [`Today is ${isoDate} (${humanDate}, UTC).`, 'Use this exact date for any recency reasoning.'].join(' ')
|
|
36
|
+
return [`Today is ${formatUtcPromptDate(now)}.`, 'Use this exact date for any recency reasoning.'].join(' ')
|
|
44
37
|
}
|
|
45
38
|
|
|
46
39
|
export function buildRecencyInstructions(tools?: ToolSet): string {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ToolLoopAgent } from 'ai'
|
|
2
2
|
|
|
3
3
|
import { aiGatewayOpenRouterResponseHealingModel } from '../ai-gateway/ai-gateway'
|
|
4
|
-
import {
|
|
4
|
+
import { buildAiGatewayDirectCacheHeaders } from '../ai-gateway/cache-headers'
|
|
5
5
|
import {
|
|
6
6
|
OPENROUTER_LOW_REASONING_PROVIDER_OPTIONS,
|
|
7
7
|
OPENROUTER_STRUCTURED_HELPER_MODEL_ID,
|
|
@@ -33,7 +33,7 @@ export function createMemoryRerankerAgent(options: CreateHelperToolLoopAgentOpti
|
|
|
33
33
|
return new ToolLoopAgent({
|
|
34
34
|
id: 'memory-reranker',
|
|
35
35
|
model: aiGatewayOpenRouterResponseHealingModel(OPENROUTER_STRUCTURED_HELPER_MODEL_ID),
|
|
36
|
-
headers:
|
|
36
|
+
headers: buildAiGatewayDirectCacheHeaders('memory-reranker'),
|
|
37
37
|
providerOptions: OPENROUTER_LOW_REASONING_PROVIDER_OPTIONS,
|
|
38
38
|
...resolveHelperAgentOptions(options),
|
|
39
39
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ToolLoopAgent } from 'ai'
|
|
2
2
|
|
|
3
3
|
import { aiGatewayOpenRouterResponseHealingModel } from '../ai-gateway/ai-gateway'
|
|
4
|
-
import {
|
|
4
|
+
import { buildAiGatewayDirectCacheHeaders } from '../ai-gateway/cache-headers'
|
|
5
5
|
import {
|
|
6
6
|
OPENROUTER_STRUCTURED_HELPER_MODEL_ID,
|
|
7
7
|
OPENROUTER_HIGH_REASONING_PROVIDER_OPTIONS,
|
|
@@ -53,7 +53,7 @@ export function createOrgMemoryAgent(options: CreateHelperToolLoopAgentOptions)
|
|
|
53
53
|
return new ToolLoopAgent({
|
|
54
54
|
id: 'org-memory',
|
|
55
55
|
model: aiGatewayOpenRouterResponseHealingModel(OPENROUTER_STRUCTURED_HELPER_MODEL_ID),
|
|
56
|
-
headers:
|
|
56
|
+
headers: buildAiGatewayDirectCacheHeaders('org-memory'),
|
|
57
57
|
providerOptions: OPENROUTER_HIGH_REASONING_PROVIDER_OPTIONS,
|
|
58
58
|
...resolveHelperAgentOptions(options),
|
|
59
59
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ToolLoopAgent } from 'ai'
|
|
2
2
|
|
|
3
3
|
import { aiGatewayModel } from '../ai-gateway/ai-gateway'
|
|
4
|
-
import {
|
|
4
|
+
import { buildAiGatewayDirectCacheHeaders } from '../ai-gateway/cache-headers'
|
|
5
5
|
import { getLeadAgentDisplayName } from '../config/agent-defaults'
|
|
6
6
|
import {
|
|
7
7
|
OPENROUTER_STRUCTURED_HELPER_MODEL_ID,
|
|
@@ -80,7 +80,7 @@ export function createRecentActivityTitleRefinerAgent(options: CreateHelperToolL
|
|
|
80
80
|
return new ToolLoopAgent({
|
|
81
81
|
id: 'recent-activity-title-refiner',
|
|
82
82
|
model: aiGatewayModel(OPENROUTER_STRUCTURED_HELPER_MODEL_ID),
|
|
83
|
-
headers:
|
|
83
|
+
headers: buildAiGatewayDirectCacheHeaders('recent-activity-title-refiner'),
|
|
84
84
|
providerOptions: OPENROUTER_HIGH_REASONING_PROVIDER_OPTIONS,
|
|
85
85
|
...resolveHelperAgentOptions(options, {
|
|
86
86
|
instructions: buildRecentActivityTitleRefinerPrompt(),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ToolLoopAgent } from 'ai'
|
|
2
2
|
|
|
3
3
|
import { aiGatewayOpenRouterResponseHealingModel } from '../ai-gateway/ai-gateway'
|
|
4
|
-
import {
|
|
4
|
+
import { buildAiGatewayDirectCacheHeaders } from '../ai-gateway/cache-headers'
|
|
5
5
|
import {
|
|
6
6
|
OPENROUTER_STRUCTURED_HELPER_MODEL_ID,
|
|
7
7
|
OPENROUTER_HIGH_REASONING_PROVIDER_OPTIONS,
|
|
@@ -67,7 +67,7 @@ export function createRegularChatMemoryDigestAgent(options: CreateHelperToolLoop
|
|
|
67
67
|
return new ToolLoopAgent({
|
|
68
68
|
id: 'regular-chat-memory-digest',
|
|
69
69
|
model: aiGatewayOpenRouterResponseHealingModel(OPENROUTER_STRUCTURED_HELPER_MODEL_ID),
|
|
70
|
-
headers:
|
|
70
|
+
headers: buildAiGatewayDirectCacheHeaders('regular-chat-memory-digest'),
|
|
71
71
|
providerOptions: OPENROUTER_HIGH_REASONING_PROVIDER_OPTIONS,
|
|
72
72
|
...resolveHelperAgentOptions(options, {
|
|
73
73
|
instructions: regularChatMemoryDigestPrompt,
|
|
@@ -2,7 +2,7 @@ import { ToolLoopAgent } from 'ai'
|
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
|
|
4
4
|
import { aiGatewayOpenRouterResponseHealingModel } from '../ai-gateway/ai-gateway'
|
|
5
|
-
import {
|
|
5
|
+
import { buildAiGatewayDirectCacheHeaders } from '../ai-gateway/cache-headers'
|
|
6
6
|
import {
|
|
7
7
|
OPENROUTER_STRUCTURED_HELPER_MODEL_ID,
|
|
8
8
|
OPENROUTER_HIGH_REASONING_PROVIDER_OPTIONS,
|
|
@@ -80,7 +80,7 @@ export function createSkillExtractorAgent(options: CreateHelperToolLoopAgentOpti
|
|
|
80
80
|
return new ToolLoopAgent({
|
|
81
81
|
id: 'skill-extractor',
|
|
82
82
|
model: aiGatewayOpenRouterResponseHealingModel(OPENROUTER_STRUCTURED_HELPER_MODEL_ID),
|
|
83
|
-
headers:
|
|
83
|
+
headers: buildAiGatewayDirectCacheHeaders('skill-extractor'),
|
|
84
84
|
providerOptions: OPENROUTER_HIGH_REASONING_PROVIDER_OPTIONS,
|
|
85
85
|
...resolveHelperAgentOptions(options, {
|
|
86
86
|
instructions: skillExtractorPrompt,
|
|
@@ -2,7 +2,7 @@ import { ToolLoopAgent } from 'ai'
|
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
|
|
4
4
|
import { aiGatewayOpenRouterResponseHealingModel } from '../ai-gateway/ai-gateway'
|
|
5
|
-
import {
|
|
5
|
+
import { buildAiGatewayDirectCacheHeaders } from '../ai-gateway/cache-headers'
|
|
6
6
|
import {
|
|
7
7
|
OPENROUTER_STRUCTURED_HELPER_MODEL_ID,
|
|
8
8
|
OPENROUTER_HIGH_REASONING_PROVIDER_OPTIONS,
|
|
@@ -70,7 +70,7 @@ export function createSkillManagerAgent(options: CreateHelperToolLoopAgentOption
|
|
|
70
70
|
return new ToolLoopAgent({
|
|
71
71
|
id: 'skill-manager',
|
|
72
72
|
model: aiGatewayOpenRouterResponseHealingModel(OPENROUTER_STRUCTURED_HELPER_MODEL_ID),
|
|
73
|
-
headers:
|
|
73
|
+
headers: buildAiGatewayDirectCacheHeaders('skill-manager'),
|
|
74
74
|
providerOptions: OPENROUTER_HIGH_REASONING_PROVIDER_OPTIONS,
|
|
75
75
|
...resolveHelperAgentOptions(options, {
|
|
76
76
|
instructions: skillManagerPrompt,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ToolLoopAgent } from 'ai'
|
|
2
2
|
|
|
3
3
|
import { aiGatewayModel } from '../ai-gateway/ai-gateway'
|
|
4
|
-
import {
|
|
4
|
+
import { buildAiGatewayDirectCacheHeaders } from '../ai-gateway/cache-headers'
|
|
5
5
|
import {
|
|
6
6
|
OPENROUTER_FAST_REASONING_MODEL_ID,
|
|
7
7
|
OPENROUTER_MINIMAL_REASONING_PROVIDER_OPTIONS,
|
|
@@ -34,7 +34,7 @@ export function createWorkstreamTitleGeneratorAgent(options: CreateHelperToolLoo
|
|
|
34
34
|
return new ToolLoopAgent({
|
|
35
35
|
id: 'workstream-title-generator',
|
|
36
36
|
model: aiGatewayModel(OPENROUTER_FAST_REASONING_MODEL_ID),
|
|
37
|
-
headers:
|
|
37
|
+
headers: buildAiGatewayDirectCacheHeaders('workstream-title-generator'),
|
|
38
38
|
providerOptions: OPENROUTER_MINIMAL_REASONING_PROVIDER_OPTIONS,
|
|
39
39
|
...resolveHelperAgentOptions(options, {
|
|
40
40
|
instructions: WORKSTREAM_TITLE_GENERATOR_PROMPT,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { aiGatewayChatModel } from '../ai-gateway/ai-gateway'
|
|
2
|
-
import {
|
|
2
|
+
import { buildAiGatewayStrictSemanticCacheHeaders } from '../ai-gateway/cache-headers'
|
|
3
3
|
import {
|
|
4
4
|
OPENROUTER_MEDIUM_REASONING_PROVIDER_OPTIONS,
|
|
5
5
|
OPENROUTER_WEB_RESEARCH_MODEL_ID,
|
|
@@ -15,7 +15,7 @@ export const researchTopicTool = createDelegatedAgentTool({
|
|
|
15
15
|
'Delegate a research task to a dedicated research agent that searches the web, fetches pages, and returns a synthesized markdown report. Call multiple instances in parallel for broad research across different topics.',
|
|
16
16
|
model: () => aiGatewayChatModel(OPENROUTER_WEB_RESEARCH_MODEL_ID),
|
|
17
17
|
providerOptions: OPENROUTER_MEDIUM_REASONING_PROVIDER_OPTIONS,
|
|
18
|
-
headers:
|
|
18
|
+
headers: buildAiGatewayStrictSemanticCacheHeaders('researchTopic'),
|
|
19
19
|
instructions: RESEARCHER_PROMPT,
|
|
20
20
|
tools: { searchWeb: searchWebTool.create(), fetchWebpage: fetchWebpageTool.create() },
|
|
21
21
|
})
|
package/src/utils/date-time.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
export { toIsoDateTimeString, toOptionalIsoDateTimeString } from '@lota-sdk/shared'
|
|
2
2
|
|
|
3
|
+
const PROMPT_DATE_FORMATTER = new Intl.DateTimeFormat('en-US', {
|
|
4
|
+
timeZone: 'UTC',
|
|
5
|
+
year: 'numeric',
|
|
6
|
+
month: 'long',
|
|
7
|
+
day: 'numeric',
|
|
8
|
+
})
|
|
9
|
+
|
|
3
10
|
export function toDatabaseDateTime(value: string | Date | null | undefined): Date | undefined {
|
|
4
11
|
if (value === null || value === undefined) return undefined
|
|
5
12
|
return value instanceof Date ? value : new Date(value)
|
|
6
13
|
}
|
|
14
|
+
|
|
15
|
+
export function formatUtcPromptDate(value: Date): string {
|
|
16
|
+
return PROMPT_DATE_FORMATTER.format(value)
|
|
17
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CHARS_PER_TOKEN_ESTIMATE } from '../../utils/string'
|
|
2
2
|
|
|
3
|
-
export const DEFAULT_FILE_SECTION_CHUNK_MAX_CHARS =
|
|
3
|
+
export const DEFAULT_FILE_SECTION_CHUNK_MAX_CHARS = 1_500_000
|
|
4
4
|
export const MIN_FILE_SECTION_CHUNK_MAX_CHARS = 4_000
|
|
5
5
|
export const DEFAULT_FILE_SECTION_CHUNK_MIN_CHARS = 10_000
|
|
6
6
|
const SECTION_SEPARATOR_LENGTH = 2
|
|
@@ -4,10 +4,11 @@ import { fileURLToPath } from 'node:url'
|
|
|
4
4
|
import type { Job, Worker } from 'bullmq'
|
|
5
5
|
|
|
6
6
|
import { chatLogger } from '../config/logger'
|
|
7
|
+
import { queueJobService } from '../services/queue-job.service'
|
|
7
8
|
import { truncateText } from '../utils/string'
|
|
8
9
|
|
|
9
|
-
export const DEFAULT_JOB_RETENTION = { removeOnComplete:
|
|
10
|
-
export const LOW_JOB_RETENTION = { removeOnComplete:
|
|
10
|
+
export const DEFAULT_JOB_RETENTION = { removeOnComplete: true, removeOnFail: { age: 24 * 60 * 60, count: 200 } }
|
|
11
|
+
export const LOW_JOB_RETENTION = { removeOnComplete: true, removeOnFail: { age: 6 * 60 * 60, count: 50 } }
|
|
11
12
|
export const LONG_JOB_LOCK_DURATION_MS = 600_000
|
|
12
13
|
|
|
13
14
|
const DEFAULT_SHUTDOWN_TIMEOUT_MS = 10_000
|
|
@@ -30,6 +31,8 @@ interface TracedWorkerJobLike {
|
|
|
30
31
|
name: string
|
|
31
32
|
attemptsMade: number | null | undefined
|
|
32
33
|
data?: unknown
|
|
34
|
+
opts?: unknown
|
|
35
|
+
timestamp?: number
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
function truncateTraceString(value: string, maxChars = MAX_TRACE_STRING_CHARS): string {
|
|
@@ -143,11 +146,36 @@ export const createWorkerShutdown = (worker: Worker, name: string, logger: typeo
|
|
|
143
146
|
}
|
|
144
147
|
}
|
|
145
148
|
|
|
146
|
-
export function createTracedWorkerProcessor<TJob extends TracedWorkerJobLike>(
|
|
147
|
-
|
|
148
|
-
processor: (job: TJob) => Promise<
|
|
149
|
-
): (job: TJob) => Promise<
|
|
150
|
-
return async (job: TJob) =>
|
|
149
|
+
export function createTracedWorkerProcessor<TJob extends TracedWorkerJobLike, TResult = void>(
|
|
150
|
+
queueName: string,
|
|
151
|
+
processor: (job: TJob) => Promise<TResult>,
|
|
152
|
+
): (job: TJob) => Promise<TResult> {
|
|
153
|
+
return async (job: TJob) => {
|
|
154
|
+
const trackedJob = {
|
|
155
|
+
queueName,
|
|
156
|
+
id: typeof job.id === 'string' || typeof job.id === 'number' ? job.id : undefined,
|
|
157
|
+
name: job.name,
|
|
158
|
+
attemptsMade: job.attemptsMade,
|
|
159
|
+
data: job.data,
|
|
160
|
+
opts: job.opts,
|
|
161
|
+
timestamp: job.timestamp,
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
await queueJobService.markAttemptStarted(trackedJob)
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
const result = await processor(job)
|
|
168
|
+
await queueJobService.markAttemptCompleted(trackedJob, result)
|
|
169
|
+
return result
|
|
170
|
+
} catch (error) {
|
|
171
|
+
try {
|
|
172
|
+
await queueJobService.markAttemptFailed(trackedJob, error)
|
|
173
|
+
} catch (persistenceError) {
|
|
174
|
+
chatLogger.error`Failed to persist queue job failure (queue=${queueName}, job=${job.id}): ${persistenceError}`
|
|
175
|
+
}
|
|
176
|
+
throw error
|
|
177
|
+
}
|
|
178
|
+
}
|
|
151
179
|
}
|
|
152
180
|
|
|
153
181
|
export const registerShutdownSignals = ({
|