@mrtdown/core 2.0.0-alpha.2 → 2.0.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/dist/cli/commands/create.d.ts +30 -0
  2. package/dist/cli/commands/create.js +189 -0
  3. package/dist/cli/commands/create.js.map +1 -0
  4. package/dist/cli/commands/list.d.ts +6 -0
  5. package/dist/cli/commands/list.js +106 -0
  6. package/dist/cli/commands/list.js.map +1 -0
  7. package/dist/cli/commands/show.d.ts +6 -0
  8. package/dist/cli/commands/show.js +156 -0
  9. package/dist/cli/commands/show.js.map +1 -0
  10. package/dist/cli/commands/validate.d.ts +6 -0
  11. package/dist/cli/commands/validate.js +19 -0
  12. package/dist/cli/commands/validate.js.map +1 -0
  13. package/dist/cli/index.d.ts +2 -0
  14. package/dist/cli/index.js +162 -0
  15. package/dist/cli/index.js.map +1 -0
  16. package/dist/index.d.ts +20 -11
  17. package/dist/index.js +20 -11
  18. package/dist/index.js.map +1 -1
  19. package/dist/llm/client.d.ts +2 -0
  20. package/dist/llm/client.js +5 -0
  21. package/dist/llm/client.js.map +1 -0
  22. package/dist/llm/common/MemoryStore.d.ts +21 -0
  23. package/dist/llm/common/MemoryStore.js +100 -0
  24. package/dist/llm/common/MemoryStore.js.map +1 -0
  25. package/dist/llm/common/MemoryStore.test.d.ts +1 -0
  26. package/dist/llm/common/MemoryStore.test.js +225 -0
  27. package/dist/llm/common/MemoryStore.test.js.map +1 -0
  28. package/dist/llm/common/formatCurrentState.d.ts +10 -0
  29. package/dist/llm/common/formatCurrentState.js +342 -0
  30. package/dist/llm/common/formatCurrentState.js.map +1 -0
  31. package/dist/llm/common/tool.d.ts +32 -0
  32. package/dist/llm/common/tool.js +6 -0
  33. package/dist/llm/common/tool.js.map +1 -0
  34. package/dist/llm/functions/extractClaimsFromNewEvidence/eval.test.d.ts +1 -0
  35. package/dist/llm/functions/extractClaimsFromNewEvidence/eval.test.js +433 -0
  36. package/dist/llm/functions/extractClaimsFromNewEvidence/eval.test.js.map +1 -0
  37. package/dist/llm/functions/extractClaimsFromNewEvidence/index.d.ts +18 -0
  38. package/dist/llm/functions/extractClaimsFromNewEvidence/index.js +153 -0
  39. package/dist/llm/functions/extractClaimsFromNewEvidence/index.js.map +1 -0
  40. package/dist/llm/functions/extractClaimsFromNewEvidence/prompt.d.ts +1 -0
  41. package/dist/llm/functions/extractClaimsFromNewEvidence/prompt.js +168 -0
  42. package/dist/llm/functions/extractClaimsFromNewEvidence/prompt.js.map +1 -0
  43. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindLinesTool.d.ts +19 -0
  44. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindLinesTool.js +65 -0
  45. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindLinesTool.js.map +1 -0
  46. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindServicesTool.d.ts +21 -0
  47. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindServicesTool.js +115 -0
  48. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindServicesTool.js.map +1 -0
  49. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindStationsTool.d.ts +24 -0
  50. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindStationsTool.js +110 -0
  51. package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindStationsTool.js.map +1 -0
  52. package/dist/llm/functions/generateIssueTitleAndSlug/index.d.ts +14 -0
  53. package/dist/llm/functions/generateIssueTitleAndSlug/index.js +38 -0
  54. package/dist/llm/functions/generateIssueTitleAndSlug/index.js.map +1 -0
  55. package/dist/llm/functions/generateIssueTitleAndSlug/prompt.d.ts +1 -0
  56. package/dist/llm/functions/generateIssueTitleAndSlug/prompt.js +23 -0
  57. package/dist/llm/functions/generateIssueTitleAndSlug/prompt.js.map +1 -0
  58. package/dist/llm/functions/translate/index.d.ts +1 -0
  59. package/dist/llm/functions/translate/index.js +59 -0
  60. package/dist/llm/functions/translate/index.js.map +1 -0
  61. package/dist/llm/functions/triageNewEvidence/eval.test.d.ts +1 -0
  62. package/dist/llm/functions/triageNewEvidence/eval.test.js +139 -0
  63. package/dist/llm/functions/triageNewEvidence/eval.test.js.map +1 -0
  64. package/dist/llm/functions/triageNewEvidence/index.d.ts +37 -0
  65. package/dist/llm/functions/triageNewEvidence/index.js +121 -0
  66. package/dist/llm/functions/triageNewEvidence/index.js.map +1 -0
  67. package/dist/llm/functions/triageNewEvidence/prompt.d.ts +1 -0
  68. package/dist/llm/functions/triageNewEvidence/prompt.js +60 -0
  69. package/dist/llm/functions/triageNewEvidence/prompt.js.map +1 -0
  70. package/dist/llm/functions/triageNewEvidence/tools/FindIssuesTool.d.ts +19 -0
  71. package/dist/llm/functions/triageNewEvidence/tools/FindIssuesTool.js +65 -0
  72. package/dist/llm/functions/triageNewEvidence/tools/FindIssuesTool.js.map +1 -0
  73. package/dist/llm/functions/triageNewEvidence/tools/GetIssueTool.d.ts +19 -0
  74. package/dist/llm/functions/triageNewEvidence/tools/GetIssueTool.js +37 -0
  75. package/dist/llm/functions/triageNewEvidence/tools/GetIssueTool.js.map +1 -0
  76. package/dist/scripts/ingestViaWebhook.d.ts +1 -0
  77. package/dist/scripts/ingestViaWebhook.js +9 -0
  78. package/dist/scripts/ingestViaWebhook.js.map +1 -0
  79. package/dist/validators/buildContext.d.ts +7 -0
  80. package/dist/validators/buildContext.js +164 -0
  81. package/dist/validators/buildContext.js.map +1 -0
  82. package/dist/validators/index.d.ts +17 -0
  83. package/dist/validators/index.js +58 -0
  84. package/dist/validators/index.js.map +1 -0
  85. package/dist/validators/issue.d.ts +13 -0
  86. package/dist/validators/issue.js +220 -0
  87. package/dist/validators/issue.js.map +1 -0
  88. package/dist/validators/landmark.d.ts +7 -0
  89. package/dist/validators/landmark.js +43 -0
  90. package/dist/validators/landmark.js.map +1 -0
  91. package/dist/validators/line.d.ts +8 -0
  92. package/dist/validators/line.js +87 -0
  93. package/dist/validators/line.js.map +1 -0
  94. package/dist/validators/operator.d.ts +7 -0
  95. package/dist/validators/operator.js +43 -0
  96. package/dist/validators/operator.js.map +1 -0
  97. package/dist/validators/service.d.ts +8 -0
  98. package/dist/validators/service.js +87 -0
  99. package/dist/validators/service.js.map +1 -0
  100. package/dist/validators/station.d.ts +8 -0
  101. package/dist/validators/station.js +93 -0
  102. package/dist/validators/station.js.map +1 -0
  103. package/dist/validators/town.d.ts +7 -0
  104. package/dist/validators/town.js +43 -0
  105. package/dist/validators/town.js.map +1 -0
  106. package/dist/validators/types.d.ts +19 -0
  107. package/dist/validators/types.js +2 -0
  108. package/dist/validators/types.js.map +1 -0
  109. package/dist/validators/utils.d.ts +2 -0
  110. package/dist/validators/utils.js +9 -0
  111. package/dist/validators/utils.js.map +1 -0
  112. package/package.json +11 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatCurrentState.js","sourceRoot":"/","sources":["llm/common/formatCurrentState.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Heading, Root } from 'mdast';\nimport { gfmToMarkdown } from 'mdast-util-gfm';\nimport { toMarkdown } from 'mdast-util-to-markdown';\nimport type { IssueBundleState } from '#repo/issue/helpers/deriveCurrentState.js';\nimport type { Evidence } from '#schema/issue/evidence.js';\nimport type { Period } from '#schema/issue/period.js';\nimport type { ServiceScope } from '#schema/issue/serviceScope.js';\n\nexport type FormatCurrentStateOptions = {\n state: IssueBundleState | null;\n evidence?: Evidence[];\n};\n\n/**\n * Format the current state as markdown for better LLM readability\n */\nexport function formatCurrentState(\n stateOrOptions: IssueBundleState | null | FormatCurrentStateOptions,\n): string {\n const options: FormatCurrentStateOptions =\n stateOrOptions != null &&\n typeof stateOrOptions === 'object' &&\n 'state' in stateOrOptions\n ? stateOrOptions\n : { state: stateOrOptions };\n const state = options.state;\n const evidence = options.evidence ?? [];\n\n if (state == null && evidence.length === 0) {\n return 'No state';\n }\n\n const services = state?.services ?? {};\n const facilities = state?.facilities ?? {};\n const impactEventIds = state?.impactEventIds ?? [];\n const relevantEvidenceIds = state != null ? collectEvidenceIds(state) : [];\n\n const root: Root = {\n type: 'root',\n children: [],\n };\n\n // Evidence Section\n root.children.push({\n type: 'heading',\n depth: 2,\n children: [{ type: 'text', value: 'Evidence' }],\n });\n\n if (evidence.length === 0) {\n root.children.push({\n type: 'paragraph',\n children: [{ type: 'text', value: 'None' }],\n });\n } else {\n for (const ev of evidence) {\n root.children.push(...formatEvidenceItem(ev));\n }\n }\n\n // Services Section\n root.children.push({\n type: 'heading',\n depth: 2,\n children: [{ type: 'text', value: 'Services' }],\n });\n\n const serviceKeys = Object.keys(services);\n if (serviceKeys.length === 0) {\n root.children.push({\n type: 'paragraph',\n children: [{ type: 'text', value: 'None' }],\n });\n } else {\n for (const key of serviceKeys) {\n const svc = services[key];\n root.children.push(\n ...formatServiceSection(\n key,\n svc.serviceId,\n svc.effect,\n svc.scopes,\n svc.periods,\n svc.causes,\n ),\n );\n }\n }\n\n // Facilities Section\n const facilitiesHeading: Heading = {\n type: 'heading',\n depth: 2,\n children: [{ type: 'text', value: 'Facilities' }],\n };\n root.children.push(facilitiesHeading);\n\n const facilityKeys = Object.keys(facilities);\n if (facilityKeys.length === 0) {\n root.children.push({\n type: 'paragraph',\n children: [{ type: 'text', value: 'None' }],\n });\n } else {\n for (const key of facilityKeys) {\n const fac = facilities[key];\n root.children.push(\n ...formatFacilitySection(\n key,\n fac.stationId,\n fac.kind,\n fac.effect,\n fac.periods,\n ),\n );\n }\n }\n\n // Impact Event IDs Section\n root.children.push({\n type: 'heading',\n depth: 2,\n children: [{ type: 'text', value: 'Impact Event IDs' }],\n });\n\n if (impactEventIds.length === 0) {\n root.children.push({\n type: 'paragraph',\n children: [{ type: 'text', value: 'None' }],\n });\n } else {\n root.children.push({\n type: 'list',\n ordered: false,\n children: impactEventIds.map((id) => ({\n type: 'listItem',\n children: [\n {\n type: 'paragraph',\n children: [{ type: 'inlineCode', value: id }],\n },\n ],\n })),\n });\n }\n\n // Relevant Evidence IDs Section\n const evidenceHeading: Heading = {\n type: 'heading',\n depth: 2,\n children: [{ type: 'text', value: 'Relevant Evidence IDs' }],\n };\n root.children.push(evidenceHeading);\n\n if (relevantEvidenceIds.length === 0) {\n root.children.push({\n type: 'paragraph',\n children: [{ type: 'text', value: 'None' }],\n });\n } else {\n root.children.push({\n type: 'list',\n ordered: false,\n children: relevantEvidenceIds.map((id) => ({\n type: 'listItem',\n children: [\n {\n type: 'paragraph',\n children: [{ type: 'inlineCode', value: id }],\n },\n ],\n })),\n });\n }\n\n return toMarkdown(root, { extensions: [gfmToMarkdown()] });\n}\n\nfunction formatEvidenceItem(ev: Evidence): Root['children'] {\n const children: Root['children'] = [];\n\n children.push({\n type: 'heading',\n depth: 3,\n children: [\n { type: 'inlineCode', value: ev.id },\n { type: 'text', value: ` (${ev.type})` },\n ],\n });\n\n children.push({\n type: 'paragraph',\n children: [\n { type: 'text', value: 'Timestamp: ' },\n { type: 'inlineCode', value: ev.ts },\n ],\n });\n\n children.push({\n type: 'paragraph',\n children: [\n { type: 'text', value: 'Source: ' },\n { type: 'inlineCode', value: ev.render?.source ?? '—' },\n ],\n });\n\n if ('sourceUrl' in ev) {\n children.push({\n type: 'paragraph',\n children: [\n { type: 'text', value: 'URL: ' },\n {\n type: 'link',\n url: ev.sourceUrl,\n children: [{ type: 'text', value: ev.sourceUrl }],\n },\n ],\n });\n }\n\n children.push({\n type: 'paragraph',\n children: [{ type: 'text', value: 'Text:' }],\n });\n children.push({\n type: 'blockquote',\n children: [\n {\n type: 'paragraph',\n children: [{ type: 'text', value: ev.text }],\n },\n ],\n });\n\n return children;\n}\n\nfunction collectEvidenceIds(state: IssueBundleState): string[] {\n const ids = new Set<string>();\n for (const prov of Object.values(state.servicesProvenance)) {\n if (prov.effect?.evidenceId) ids.add(prov.effect.evidenceId);\n if (prov.scopes?.evidenceId) ids.add(prov.scopes.evidenceId);\n if (prov.periods?.evidenceId) ids.add(prov.periods.evidenceId);\n if (prov.causes?.evidenceId) ids.add(prov.causes.evidenceId);\n }\n for (const prov of Object.values(state.facilitiesProvenance)) {\n if (prov.effect?.evidenceId) ids.add(prov.effect.evidenceId);\n if (prov.periods?.evidenceId) ids.add(prov.periods.evidenceId);\n }\n return [...ids];\n}\n\nfunction formatServiceSection(\n key: string,\n serviceId: string,\n effect: { kind: string } | null,\n scopes: ServiceScope[],\n periods: Period[],\n causes: string[],\n): Root['children'] {\n const children: Root['children'] = [];\n\n children.push({\n type: 'heading',\n depth: 3,\n children: [{ type: 'text', value: key }],\n });\n\n children.push({\n type: 'paragraph',\n children: [\n { type: 'text', value: 'Service ID: ' },\n { type: 'inlineCode', value: serviceId },\n ],\n });\n\n children.push({\n type: 'paragraph',\n children: [\n { type: 'text', value: 'Effect: ' },\n { type: 'inlineCode', value: effect?.kind ?? 'null' },\n ],\n });\n\n if (scopes.length > 0) {\n children.push({\n type: 'paragraph',\n children: [{ type: 'text', value: 'Scopes:' }],\n });\n children.push({\n type: 'list',\n ordered: false,\n children: scopes.map((scope) => ({\n type: 'listItem',\n children: [\n {\n type: 'paragraph',\n children: [{ type: 'inlineCode', value: formatScope(scope) }],\n },\n ],\n })),\n });\n }\n\n if (periods.length > 0) {\n children.push({\n type: 'paragraph',\n children: [{ type: 'text', value: 'Periods:' }],\n });\n children.push({\n type: 'list',\n ordered: false,\n children: periods.map((period, i) => ({\n type: 'listItem',\n children: [\n {\n type: 'paragraph',\n children: [{ type: 'text', value: formatPeriod(period, i) }],\n },\n ],\n })),\n });\n }\n\n if (causes.length > 0) {\n children.push({\n type: 'paragraph',\n children: [\n { type: 'text', value: 'Causes: ' },\n { type: 'inlineCode', value: causes.join(', ') },\n ],\n });\n }\n\n return children;\n}\n\nfunction formatFacilitySection(\n key: string,\n stationId: string,\n kind: string,\n effect: { kind: string } | null,\n periods: Period[],\n): Root['children'] {\n const children: Root['children'] = [];\n\n children.push({\n type: 'heading',\n depth: 3,\n children: [{ type: 'text', value: key }],\n });\n\n children.push({\n type: 'paragraph',\n children: [\n { type: 'text', value: 'Station: ' },\n { type: 'inlineCode', value: stationId },\n { type: 'text', value: ', Kind: ' },\n { type: 'inlineCode', value: kind },\n ],\n });\n\n children.push({\n type: 'paragraph',\n children: [\n { type: 'text', value: 'Effect: ' },\n { type: 'inlineCode', value: effect?.kind ?? 'null' },\n ],\n });\n\n if (periods.length > 0) {\n children.push({\n type: 'paragraph',\n children: [{ type: 'text', value: 'Periods:' }],\n });\n children.push({\n type: 'list',\n ordered: false,\n children: periods.map((period, i) => ({\n type: 'listItem',\n children: [\n {\n type: 'paragraph',\n children: [{ type: 'text', value: formatPeriod(period, i) }],\n },\n ],\n })),\n });\n }\n\n return children;\n}\n\nfunction formatScope(scope: ServiceScope): string {\n switch (scope.type) {\n case 'service.whole':\n return scope.type;\n case 'service.segment':\n return `${scope.type} (${scope.fromStationId} → ${scope.toStationId})`;\n case 'service.point':\n return `${scope.type} (${scope.stationId})`;\n }\n}\n\nfunction formatPeriod(period: Period, index: number): string {\n switch (period.kind) {\n case 'fixed':\n return `[${index}] fixed: ${period.startAt} → ${period.endAt ?? 'ongoing'}`;\n case 'recurring':\n return `[${index}] recurring ${period.frequency}: ${period.startAt}–${period.endAt} ${period.timeWindow.startAt}–${period.timeWindow.endAt}`;\n }\n}\n"]}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * A generic class for LLM tools.
3
+ */
4
+ export declare abstract class Tool<TParams = any> {
5
+ /**
6
+ * The name of the tool.
7
+ */
8
+ abstract name: string;
9
+ /**
10
+ * The description of the tool.
11
+ */
12
+ abstract description: string;
13
+ /**
14
+ * The JSON schema for the tool's parameters.
15
+ */
16
+ abstract get paramsSchema(): {
17
+ [key: string]: unknown;
18
+ };
19
+ /**
20
+ * Parse the parameters into a typed object.
21
+ * @param params
22
+ * @returns
23
+ */
24
+ abstract parseParams(params: unknown): TParams;
25
+ /**
26
+ * Run the tool with the given parameters.
27
+ * @param param
28
+ * @returns
29
+ */
30
+ abstract runner(param: TParams): Promise<string>;
31
+ }
32
+ export type ToolRegistry = Record<string, Tool>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * A generic class for LLM tools.
3
+ */
4
+ export class Tool {
5
+ }
6
+ //# sourceMappingURL=tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.js","sourceRoot":"/","sources":["llm/common/tool.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAgB,IAAI;CA6BzB","sourcesContent":["/**\n * A generic class for LLM tools.\n */\nexport abstract class Tool<TParams = any> {\n /**\n * The name of the tool.\n */\n public abstract name: string;\n\n /**\n * The description of the tool.\n */\n public abstract description: string;\n\n /**\n * The JSON schema for the tool's parameters.\n */\n public abstract get paramsSchema(): { [key: string]: unknown };\n\n /**\n * Parse the parameters into a typed object.\n * @param params\n * @returns\n */\n public abstract parseParams(params: unknown): TParams;\n\n /**\n * Run the tool with the given parameters.\n * @param param\n * @returns\n */\n public abstract runner(param: TParams): Promise<string>;\n}\n\nexport type ToolRegistry = Record<string, Tool>;\n"]}
@@ -0,0 +1 @@
1
+ import 'dotenv/config';
@@ -0,0 +1,433 @@
1
+ import 'dotenv/config';
2
+ import { resolve } from 'node:path';
3
+ import { describe } from 'vitest';
4
+ import { describeEval, StructuredOutputScorer } from 'vitest-evals';
5
+ import { FileStore } from '#repo/common/FileStore.js';
6
+ import { MRTDownRepository } from '#repo/MRTDownRepository.js';
7
+ import { assert } from '#util/assert.js';
8
+ import { extractClaimsFromNewEvidence, } from './index.js';
9
+ describe('extractClaimsFromNewEvidence', () => {
10
+ describeEval('should extract claims from new disruption evidence', {
11
+ // @ts-expect-error input is a string in the vitest-evals library
12
+ async data() {
13
+ const store = new FileStore(resolve(import.meta.dirname, '../../fixtures/data'));
14
+ const repo = new MRTDownRepository({ store });
15
+ const issueBundle = repo.issues.get('2026-01-01-tgl-train-fault');
16
+ assert(issueBundle != null, 'Issue bundle not found');
17
+ return [
18
+ {
19
+ input: {
20
+ newEvidence: {
21
+ ts: '2026-01-01T07:10:00+08:00',
22
+ text: '[TGL] Due to a track fault at Tengah, train services on the Tengah Line are delayed between Bukit Batok and Bukit Merah Central',
23
+ },
24
+ repo,
25
+ // This is used by vitest-evals as the test name, as the library expects `input` to be a string.
26
+ toString() {
27
+ return '[DISRUPTION] Expansion of scope';
28
+ },
29
+ },
30
+ expected: {
31
+ claims: [
32
+ {
33
+ entity: {
34
+ type: 'service',
35
+ serviceId: 'TGL_MAIN_E',
36
+ },
37
+ effect: {
38
+ facility: null,
39
+ service: {
40
+ kind: 'delay',
41
+ duration: null,
42
+ },
43
+ },
44
+ statusSignal: 'open',
45
+ scopes: {
46
+ service: [
47
+ {
48
+ type: 'service.segment',
49
+ fromStationId: 'BBT',
50
+ toStationId: 'BMC',
51
+ },
52
+ ],
53
+ },
54
+ timeHints: {
55
+ kind: 'start-only',
56
+ startAt: '2026-01-01T07:10:00+08:00',
57
+ },
58
+ causes: ['track.fault'],
59
+ },
60
+ {
61
+ entity: {
62
+ type: 'service',
63
+ serviceId: 'TGL_MAIN_W',
64
+ },
65
+ effect: {
66
+ facility: null,
67
+ service: {
68
+ kind: 'delay',
69
+ duration: null,
70
+ },
71
+ },
72
+ statusSignal: 'open',
73
+ scopes: {
74
+ service: [
75
+ {
76
+ type: 'service.segment',
77
+ fromStationId: 'BMC',
78
+ toStationId: 'BBT',
79
+ },
80
+ ],
81
+ },
82
+ timeHints: {
83
+ kind: 'start-only',
84
+ startAt: '2026-01-01T07:10:00+08:00',
85
+ },
86
+ causes: ['track.fault'],
87
+ },
88
+ ],
89
+ },
90
+ },
91
+ {
92
+ input: {
93
+ newEvidence: {
94
+ ts: '2026-01-01T07:10:00+08:00',
95
+ text: '[TGL] CLEARED: Fault has been cleared. Train service has resumed.',
96
+ },
97
+ repo,
98
+ // This is used by vitest-evals as the test name, as the library expects `input` to be a string.
99
+ toString() {
100
+ return '[DISRUPTION] Issue resolved';
101
+ },
102
+ },
103
+ expected: {
104
+ claims: [
105
+ {
106
+ entity: {
107
+ type: 'service',
108
+ serviceId: 'TGL_MAIN_E',
109
+ },
110
+ effect: {
111
+ service: null,
112
+ facility: null,
113
+ },
114
+ scopes: {
115
+ service: [{ type: 'service.whole' }],
116
+ },
117
+ statusSignal: 'cleared',
118
+ timeHints: {
119
+ kind: 'end-only',
120
+ endAt: '2026-01-01T07:10:00+08:00',
121
+ },
122
+ causes: null,
123
+ },
124
+ {
125
+ entity: {
126
+ type: 'service',
127
+ serviceId: 'TGL_MAIN_W',
128
+ },
129
+ effect: {
130
+ service: null,
131
+ facility: null,
132
+ },
133
+ statusSignal: 'cleared',
134
+ scopes: {
135
+ service: [{ type: 'service.whole' }],
136
+ },
137
+ timeHints: {
138
+ kind: 'end-only',
139
+ endAt: '2026-01-01T07:10:00+08:00',
140
+ },
141
+ causes: null,
142
+ },
143
+ ],
144
+ },
145
+ },
146
+ {
147
+ input: {
148
+ newEvidence: {
149
+ ts: '2026-01-01T07:10:00+08:00',
150
+ text: '[TGL] UPDATE: For alternative travel options, please refer to https://t.co/Le6ROZGqsm',
151
+ },
152
+ repo,
153
+ // This is used by vitest-evals as the test name, as the library expects `input` to be a string.
154
+ toString() {
155
+ return '[DISRUPTION] Irrelevant update';
156
+ },
157
+ },
158
+ expected: {
159
+ claims: [],
160
+ },
161
+ },
162
+ ];
163
+ },
164
+ async task(input) {
165
+ const result = await extractClaimsFromNewEvidence(input);
166
+ return JSON.stringify(result);
167
+ },
168
+ scorers: [StructuredOutputScorer()],
169
+ });
170
+ describeEval('should compute the impact of new maintenance evidence', {
171
+ // @ts-expect-error input is a string in the vitest-evals library
172
+ async data() {
173
+ const store = new FileStore(resolve(import.meta.dirname, '../../fixtures/data'));
174
+ const repo = new MRTDownRepository({ store });
175
+ return [
176
+ {
177
+ input: {
178
+ newEvidence: {
179
+ ts: '2026-01-01T07:10:00+08:00',
180
+ text: '[TGL] The Tengah Line will be closed for maintenance on Sat &amp; Sun from 7 to 8 February 2026.',
181
+ },
182
+ repo,
183
+ // This is used by vitest-evals as the test name, as the library expects `input` to be a string.
184
+ toString() {
185
+ return '[MAINTENANCE] New issue';
186
+ },
187
+ },
188
+ expected: {
189
+ claims: [
190
+ {
191
+ entity: {
192
+ type: 'service',
193
+ serviceId: 'TGL_MAIN_E',
194
+ },
195
+ effect: {
196
+ service: { kind: 'no-service' },
197
+ facility: null,
198
+ },
199
+ statusSignal: 'planned',
200
+ scopes: {
201
+ service: [{ type: 'service.whole' }],
202
+ },
203
+ timeHints: {
204
+ kind: 'fixed',
205
+ startAt: '2026-02-07T00:00:00+08:00',
206
+ endAt: '2026-02-09T00:00:00+08:00',
207
+ },
208
+ causes: null,
209
+ },
210
+ {
211
+ entity: {
212
+ type: 'service',
213
+ serviceId: 'TGL_MAIN_W',
214
+ },
215
+ effect: {
216
+ service: { kind: 'no-service' },
217
+ facility: null,
218
+ },
219
+ statusSignal: 'planned',
220
+ scopes: {
221
+ service: [{ type: 'service.whole' }],
222
+ },
223
+ timeHints: {
224
+ kind: 'fixed',
225
+ startAt: '2026-02-07T00:00:00+08:00',
226
+ endAt: '2026-02-09T00:00:00+08:00',
227
+ },
228
+ causes: null,
229
+ },
230
+ ],
231
+ },
232
+ },
233
+ {
234
+ input: {
235
+ newEvidence: {
236
+ ts: '2026-01-01T07:10:00+08:00',
237
+ text: 'To continue testing the integrated systems and trains in preparation for Stage 2 of #TGL, train services from Bukit Batok to Bukit Merah Central will start later at 6.30am and end at 9pm daily from 1 to 8 February 2026.',
238
+ },
239
+ repo,
240
+ // This is used by vitest-evals as the test name, as the library expects `input` to be a string.
241
+ toString() {
242
+ return '[MAINTENANCE] Service hour adjustments';
243
+ },
244
+ },
245
+ expected: {
246
+ claims: [
247
+ {
248
+ entity: {
249
+ type: 'service',
250
+ serviceId: 'TGL_MAIN_E',
251
+ },
252
+ effect: {
253
+ service: {
254
+ kind: 'service-hours-adjustment',
255
+ },
256
+ facility: null,
257
+ },
258
+ statusSignal: 'planned',
259
+ scopes: {
260
+ service: [
261
+ {
262
+ type: 'service.segment',
263
+ fromStationId: 'BBT',
264
+ toStationId: 'BMC',
265
+ },
266
+ ],
267
+ },
268
+ timeHints: {
269
+ kind: 'recurring',
270
+ frequency: 'daily',
271
+ startAt: '2026-02-01T21:00:00+08:00',
272
+ endAt: '2026-02-08T21:00:00+08:00',
273
+ daysOfWeek: null,
274
+ timeZone: 'Asia/Singapore',
275
+ timeWindow: {
276
+ startAt: '21:00:00',
277
+ endAt: '06:30:00',
278
+ },
279
+ excludedDates: null,
280
+ },
281
+ causes: ['system.upgrade'],
282
+ },
283
+ {
284
+ entity: {
285
+ type: 'service',
286
+ serviceId: 'TGL_MAIN_W',
287
+ },
288
+ effect: {
289
+ service: {
290
+ kind: 'service-hours-adjustment',
291
+ },
292
+ facility: null,
293
+ },
294
+ statusSignal: 'planned',
295
+ scopes: {
296
+ service: [
297
+ {
298
+ type: 'service.segment',
299
+ fromStationId: 'BMC',
300
+ toStationId: 'BBT',
301
+ },
302
+ ],
303
+ },
304
+ timeHints: {
305
+ kind: 'recurring',
306
+ frequency: 'daily',
307
+ startAt: '2026-02-01T21:00:00+08:00',
308
+ endAt: '2026-02-08T21:00:00+08:00',
309
+ daysOfWeek: null,
310
+ timeZone: 'Asia/Singapore',
311
+ timeWindow: {
312
+ startAt: '21:00:00',
313
+ endAt: '06:30:00',
314
+ },
315
+ excludedDates: null,
316
+ },
317
+ causes: ['system.upgrade'],
318
+ },
319
+ ],
320
+ },
321
+ },
322
+ {
323
+ input: {
324
+ newEvidence: {
325
+ ts: '2026-01-10T22:00:00+08:00',
326
+ text: 'The Tengah & Seletar Lines train service will start at 10am on 18 Feb. For MRT Shuttle Bus pick-up points, visit http://t.co/fwb2wOqI',
327
+ },
328
+ repo,
329
+ // This is used by vitest-evals as the test name, as the library expects `input` to be a string.
330
+ toString() {
331
+ return '[MAINTENANCE] Service hour adjustments';
332
+ },
333
+ },
334
+ expected: {
335
+ claims: [
336
+ {
337
+ entity: {
338
+ type: 'service',
339
+ serviceId: 'TGL_MAIN_E',
340
+ },
341
+ effect: {
342
+ service: { kind: 'service-hours-adjustment' },
343
+ facility: null,
344
+ },
345
+ statusSignal: 'planned',
346
+ scopes: {
347
+ service: [{ type: 'service.whole' }],
348
+ },
349
+ timeHints: {
350
+ kind: 'fixed',
351
+ startAt: '2026-02-18T00:00:00+08:00',
352
+ endAt: '2026-02-18T10:00:00+08:00',
353
+ },
354
+ causes: null,
355
+ },
356
+ {
357
+ entity: {
358
+ type: 'service',
359
+ serviceId: 'TGL_MAIN_W',
360
+ },
361
+ effect: {
362
+ service: { kind: 'service-hours-adjustment' },
363
+ facility: null,
364
+ },
365
+ statusSignal: 'planned',
366
+ scopes: {
367
+ service: [{ type: 'service.whole' }],
368
+ },
369
+ timeHints: {
370
+ kind: 'fixed',
371
+ startAt: '2026-02-18T00:00:00+08:00',
372
+ endAt: '2026-02-18T10:00:00+08:00',
373
+ },
374
+ causes: null,
375
+ },
376
+ {
377
+ entity: {
378
+ type: 'service',
379
+ serviceId: 'SLL_MAIN_N',
380
+ },
381
+ effect: {
382
+ service: { kind: 'service-hours-adjustment' },
383
+ facility: null,
384
+ },
385
+ scopes: {
386
+ service: [{ type: 'service.whole' }],
387
+ },
388
+ timeHints: {
389
+ kind: 'fixed',
390
+ startAt: '2026-02-18T00:00:00+08:00',
391
+ endAt: '2026-02-18T10:00:00+08:00',
392
+ },
393
+ statusSignal: 'planned',
394
+ causes: null,
395
+ },
396
+ {
397
+ entity: {
398
+ type: 'service',
399
+ serviceId: 'SLL_MAIN_S',
400
+ },
401
+ effect: {
402
+ service: { kind: 'service-hours-adjustment' },
403
+ facility: null,
404
+ },
405
+ scopes: {
406
+ service: [{ type: 'service.whole' }],
407
+ },
408
+ timeHints: {
409
+ kind: 'fixed',
410
+ startAt: '2026-02-18T00:00:00+08:00',
411
+ endAt: '2026-02-18T10:00:00+08:00',
412
+ },
413
+ statusSignal: 'planned',
414
+ causes: null,
415
+ },
416
+ ],
417
+ },
418
+ },
419
+ ];
420
+ },
421
+ async task(input) {
422
+ const result = await extractClaimsFromNewEvidence(input);
423
+ return JSON.stringify(result);
424
+ },
425
+ scorers: [
426
+ StructuredOutputScorer({
427
+ match: 'fuzzy',
428
+ fuzzyOptions: { ignoreArrayOrder: true },
429
+ }),
430
+ ],
431
+ });
432
+ });
433
+ //# sourceMappingURL=eval.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval.test.js","sourceRoot":"/","sources":["llm/functions/extractClaimsFromNewEvidence/eval.test.ts"],"names":[],"mappings":"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","sourcesContent":["import 'dotenv/config';\n\nimport { resolve } from 'node:path';\nimport { describe } from 'vitest';\nimport { describeEval, StructuredOutputScorer } from 'vitest-evals';\nimport { FileStore } from '#repo/common/FileStore.js';\nimport { MRTDownRepository } from '#repo/MRTDownRepository.js';\nimport { assert } from '#util/assert.js';\nimport {\n type ExtractClaimsFromNewEvidenceParams,\n type ExtractClaimsFromNewEvidenceResult,\n extractClaimsFromNewEvidence,\n} from './index.js';\n\ndescribe('extractClaimsFromNewEvidence', () => {\n describeEval('should extract claims from new disruption evidence', {\n // @ts-expect-error input is a string in the vitest-evals library\n async data() {\n const store = new FileStore(\n resolve(import.meta.dirname, '../../fixtures/data'),\n );\n const repo = new MRTDownRepository({ store });\n const issueBundle = repo.issues.get('2026-01-01-tgl-train-fault');\n assert(issueBundle != null, 'Issue bundle not found');\n\n return [\n {\n input: {\n newEvidence: {\n ts: '2026-01-01T07:10:00+08:00',\n text: '[TGL] Due to a track fault at Tengah, train services on the Tengah Line are delayed between Bukit Batok and Bukit Merah Central',\n },\n repo,\n // This is used by vitest-evals as the test name, as the library expects `input` to be a string.\n toString() {\n return '[DISRUPTION] Expansion of scope';\n },\n },\n expected: {\n claims: [\n {\n entity: {\n type: 'service',\n serviceId: 'TGL_MAIN_E',\n },\n effect: {\n facility: null,\n service: {\n kind: 'delay',\n duration: null,\n },\n },\n statusSignal: 'open',\n scopes: {\n service: [\n {\n type: 'service.segment',\n fromStationId: 'BBT',\n toStationId: 'BMC',\n },\n ],\n },\n timeHints: {\n kind: 'start-only',\n startAt: '2026-01-01T07:10:00+08:00',\n },\n causes: ['track.fault'],\n },\n {\n entity: {\n type: 'service',\n serviceId: 'TGL_MAIN_W',\n },\n effect: {\n facility: null,\n service: {\n kind: 'delay',\n duration: null,\n },\n },\n statusSignal: 'open',\n scopes: {\n service: [\n {\n type: 'service.segment',\n fromStationId: 'BMC',\n toStationId: 'BBT',\n },\n ],\n },\n timeHints: {\n kind: 'start-only',\n startAt: '2026-01-01T07:10:00+08:00',\n },\n causes: ['track.fault'],\n },\n ],\n },\n },\n {\n input: {\n newEvidence: {\n ts: '2026-01-01T07:10:00+08:00',\n text: '[TGL] CLEARED: Fault has been cleared. Train service has resumed.',\n },\n repo,\n // This is used by vitest-evals as the test name, as the library expects `input` to be a string.\n toString() {\n return '[DISRUPTION] Issue resolved';\n },\n },\n expected: {\n claims: [\n {\n entity: {\n type: 'service',\n serviceId: 'TGL_MAIN_E',\n },\n effect: {\n service: null,\n facility: null,\n },\n scopes: {\n service: [{ type: 'service.whole' }],\n },\n statusSignal: 'cleared',\n timeHints: {\n kind: 'end-only',\n endAt: '2026-01-01T07:10:00+08:00',\n },\n causes: null,\n },\n {\n entity: {\n type: 'service',\n serviceId: 'TGL_MAIN_W',\n },\n effect: {\n service: null,\n facility: null,\n },\n statusSignal: 'cleared',\n scopes: {\n service: [{ type: 'service.whole' }],\n },\n timeHints: {\n kind: 'end-only',\n endAt: '2026-01-01T07:10:00+08:00',\n },\n causes: null,\n },\n ],\n },\n },\n {\n input: {\n newEvidence: {\n ts: '2026-01-01T07:10:00+08:00',\n text: '[TGL] UPDATE: For alternative travel options, please refer to https://t.co/Le6ROZGqsm',\n },\n repo,\n // This is used by vitest-evals as the test name, as the library expects `input` to be a string.\n toString() {\n return '[DISRUPTION] Irrelevant update';\n },\n },\n expected: {\n claims: [],\n },\n },\n ] satisfies {\n input: ExtractClaimsFromNewEvidenceParams & { toString(): string };\n expected: ExtractClaimsFromNewEvidenceResult;\n }[];\n },\n async task(input) {\n const result = await extractClaimsFromNewEvidence(\n input as unknown as ExtractClaimsFromNewEvidenceParams,\n );\n return JSON.stringify(result);\n },\n scorers: [StructuredOutputScorer()],\n });\n describeEval('should compute the impact of new maintenance evidence', {\n // @ts-expect-error input is a string in the vitest-evals library\n async data() {\n const store = new FileStore(\n resolve(import.meta.dirname, '../../fixtures/data'),\n );\n const repo = new MRTDownRepository({ store });\n\n return [\n {\n input: {\n newEvidence: {\n ts: '2026-01-01T07:10:00+08:00',\n text: '[TGL] The Tengah Line will be closed for maintenance on Sat &amp; Sun from 7 to 8 February 2026.',\n },\n repo,\n // This is used by vitest-evals as the test name, as the library expects `input` to be a string.\n toString() {\n return '[MAINTENANCE] New issue';\n },\n },\n expected: {\n claims: [\n {\n entity: {\n type: 'service',\n serviceId: 'TGL_MAIN_E',\n },\n effect: {\n service: { kind: 'no-service' },\n facility: null,\n },\n statusSignal: 'planned',\n scopes: {\n service: [{ type: 'service.whole' }],\n },\n timeHints: {\n kind: 'fixed',\n startAt: '2026-02-07T00:00:00+08:00',\n endAt: '2026-02-09T00:00:00+08:00',\n },\n causes: null,\n },\n {\n entity: {\n type: 'service',\n serviceId: 'TGL_MAIN_W',\n },\n effect: {\n service: { kind: 'no-service' },\n facility: null,\n },\n statusSignal: 'planned',\n scopes: {\n service: [{ type: 'service.whole' }],\n },\n timeHints: {\n kind: 'fixed',\n startAt: '2026-02-07T00:00:00+08:00',\n endAt: '2026-02-09T00:00:00+08:00',\n },\n causes: null,\n },\n ],\n },\n },\n {\n input: {\n newEvidence: {\n ts: '2026-01-01T07:10:00+08:00',\n text: 'To continue testing the integrated systems and trains in preparation for Stage 2 of #TGL, train services from Bukit Batok to Bukit Merah Central will start later at 6.30am and end at 9pm daily from 1 to 8 February 2026.',\n },\n repo,\n // This is used by vitest-evals as the test name, as the library expects `input` to be a string.\n toString() {\n return '[MAINTENANCE] Service hour adjustments';\n },\n },\n expected: {\n claims: [\n {\n entity: {\n type: 'service',\n serviceId: 'TGL_MAIN_E',\n },\n effect: {\n service: {\n kind: 'service-hours-adjustment',\n },\n facility: null,\n },\n statusSignal: 'planned',\n scopes: {\n service: [\n {\n type: 'service.segment',\n fromStationId: 'BBT',\n toStationId: 'BMC',\n },\n ],\n },\n timeHints: {\n kind: 'recurring',\n frequency: 'daily',\n startAt: '2026-02-01T21:00:00+08:00',\n endAt: '2026-02-08T21:00:00+08:00',\n daysOfWeek: null,\n timeZone: 'Asia/Singapore',\n timeWindow: {\n startAt: '21:00:00',\n endAt: '06:30:00',\n },\n excludedDates: null,\n },\n causes: ['system.upgrade'],\n },\n {\n entity: {\n type: 'service',\n serviceId: 'TGL_MAIN_W',\n },\n effect: {\n service: {\n kind: 'service-hours-adjustment',\n },\n facility: null,\n },\n statusSignal: 'planned',\n scopes: {\n service: [\n {\n type: 'service.segment',\n fromStationId: 'BMC',\n toStationId: 'BBT',\n },\n ],\n },\n timeHints: {\n kind: 'recurring',\n frequency: 'daily',\n startAt: '2026-02-01T21:00:00+08:00',\n endAt: '2026-02-08T21:00:00+08:00',\n daysOfWeek: null,\n timeZone: 'Asia/Singapore',\n timeWindow: {\n startAt: '21:00:00',\n endAt: '06:30:00',\n },\n excludedDates: null,\n },\n causes: ['system.upgrade'],\n },\n ],\n },\n },\n {\n input: {\n newEvidence: {\n ts: '2026-01-10T22:00:00+08:00',\n text: 'The Tengah & Seletar Lines train service will start at 10am on 18 Feb. For MRT Shuttle Bus pick-up points, visit http://t.co/fwb2wOqI',\n },\n repo,\n // This is used by vitest-evals as the test name, as the library expects `input` to be a string.\n toString() {\n return '[MAINTENANCE] Service hour adjustments';\n },\n },\n expected: {\n claims: [\n {\n entity: {\n type: 'service',\n serviceId: 'TGL_MAIN_E',\n },\n effect: {\n service: { kind: 'service-hours-adjustment' },\n facility: null,\n },\n statusSignal: 'planned',\n scopes: {\n service: [{ type: 'service.whole' }],\n },\n timeHints: {\n kind: 'fixed',\n startAt: '2026-02-18T00:00:00+08:00',\n endAt: '2026-02-18T10:00:00+08:00',\n },\n causes: null,\n },\n {\n entity: {\n type: 'service',\n serviceId: 'TGL_MAIN_W',\n },\n effect: {\n service: { kind: 'service-hours-adjustment' },\n facility: null,\n },\n statusSignal: 'planned',\n scopes: {\n service: [{ type: 'service.whole' }],\n },\n timeHints: {\n kind: 'fixed',\n startAt: '2026-02-18T00:00:00+08:00',\n endAt: '2026-02-18T10:00:00+08:00',\n },\n causes: null,\n },\n {\n entity: {\n type: 'service',\n serviceId: 'SLL_MAIN_N',\n },\n effect: {\n service: { kind: 'service-hours-adjustment' },\n facility: null,\n },\n scopes: {\n service: [{ type: 'service.whole' }],\n },\n timeHints: {\n kind: 'fixed',\n startAt: '2026-02-18T00:00:00+08:00',\n endAt: '2026-02-18T10:00:00+08:00',\n },\n statusSignal: 'planned',\n causes: null,\n },\n {\n entity: {\n type: 'service',\n serviceId: 'SLL_MAIN_S',\n },\n effect: {\n service: { kind: 'service-hours-adjustment' },\n facility: null,\n },\n scopes: {\n service: [{ type: 'service.whole' }],\n },\n timeHints: {\n kind: 'fixed',\n startAt: '2026-02-18T00:00:00+08:00',\n endAt: '2026-02-18T10:00:00+08:00',\n },\n statusSignal: 'planned',\n causes: null,\n },\n ],\n },\n },\n ] satisfies {\n input: ExtractClaimsFromNewEvidenceParams & { toString(): string };\n expected: ExtractClaimsFromNewEvidenceResult;\n }[];\n },\n async task(input) {\n const result = await extractClaimsFromNewEvidence(\n input as unknown as ExtractClaimsFromNewEvidenceParams,\n );\n return JSON.stringify(result);\n },\n scorers: [\n StructuredOutputScorer({\n match: 'fuzzy',\n fuzzyOptions: { ignoreArrayOrder: true },\n }),\n ],\n });\n});\n"]}
@@ -0,0 +1,18 @@
1
+ import type { MRTDownRepository } from '#repo/MRTDownRepository.js';
2
+ import { type Claim } from '#schema/issue/claim.js';
3
+ export interface ExtractClaimsFromNewEvidenceParams {
4
+ newEvidence: {
5
+ ts: string;
6
+ text: string;
7
+ };
8
+ repo: MRTDownRepository;
9
+ }
10
+ export type ExtractClaimsFromNewEvidenceResult = {
11
+ claims: Claim[];
12
+ };
13
+ /**
14
+ * Extract claims from new evidence.
15
+ * @param params
16
+ * @returns
17
+ */
18
+ export declare function extractClaimsFromNewEvidence(params: ExtractClaimsFromNewEvidenceParams): Promise<ExtractClaimsFromNewEvidenceResult>;