@framers/agentos 0.2.6 → 0.2.8

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 (93) hide show
  1. package/dist/ingest-router/IngestRouter.d.ts +72 -0
  2. package/dist/ingest-router/IngestRouter.d.ts.map +1 -0
  3. package/dist/ingest-router/IngestRouter.js +98 -0
  4. package/dist/ingest-router/IngestRouter.js.map +1 -0
  5. package/dist/ingest-router/classifier.d.ts +63 -0
  6. package/dist/ingest-router/classifier.d.ts.map +1 -0
  7. package/dist/ingest-router/classifier.js +111 -0
  8. package/dist/ingest-router/classifier.js.map +1 -0
  9. package/dist/ingest-router/costs.d.ts +48 -0
  10. package/dist/ingest-router/costs.d.ts.map +1 -0
  11. package/dist/ingest-router/costs.js +63 -0
  12. package/dist/ingest-router/costs.js.map +1 -0
  13. package/dist/ingest-router/dispatcher.d.ts +35 -0
  14. package/dist/ingest-router/dispatcher.d.ts.map +1 -0
  15. package/dist/ingest-router/dispatcher.js +32 -0
  16. package/dist/ingest-router/dispatcher.js.map +1 -0
  17. package/dist/ingest-router/index.d.ts +43 -0
  18. package/dist/ingest-router/index.d.ts.map +1 -0
  19. package/dist/ingest-router/index.js +37 -0
  20. package/dist/ingest-router/index.js.map +1 -0
  21. package/dist/ingest-router/routing-tables.d.ts +122 -0
  22. package/dist/ingest-router/routing-tables.d.ts.map +1 -0
  23. package/dist/ingest-router/routing-tables.js +145 -0
  24. package/dist/ingest-router/routing-tables.js.map +1 -0
  25. package/dist/ingest-router/select-strategy.d.ts +67 -0
  26. package/dist/ingest-router/select-strategy.d.ts.map +1 -0
  27. package/dist/ingest-router/select-strategy.js +100 -0
  28. package/dist/ingest-router/select-strategy.js.map +1 -0
  29. package/dist/memory-router/MemoryRouter.d.ts +195 -0
  30. package/dist/memory-router/MemoryRouter.d.ts.map +1 -0
  31. package/dist/memory-router/MemoryRouter.js +155 -0
  32. package/dist/memory-router/MemoryRouter.js.map +1 -0
  33. package/dist/memory-router/adaptive.d.ts +142 -0
  34. package/dist/memory-router/adaptive.d.ts.map +1 -0
  35. package/dist/memory-router/adaptive.js +202 -0
  36. package/dist/memory-router/adaptive.js.map +1 -0
  37. package/dist/memory-router/backend-costs.d.ts +67 -0
  38. package/dist/memory-router/backend-costs.d.ts.map +1 -0
  39. package/dist/memory-router/backend-costs.js +136 -0
  40. package/dist/memory-router/backend-costs.js.map +1 -0
  41. package/dist/memory-router/classifier.d.ts +169 -0
  42. package/dist/memory-router/classifier.d.ts.map +1 -0
  43. package/dist/memory-router/classifier.js +193 -0
  44. package/dist/memory-router/classifier.js.map +1 -0
  45. package/dist/memory-router/dispatcher.d.ts +115 -0
  46. package/dist/memory-router/dispatcher.d.ts.map +1 -0
  47. package/dist/memory-router/dispatcher.js +84 -0
  48. package/dist/memory-router/dispatcher.js.map +1 -0
  49. package/dist/memory-router/index.d.ts +126 -0
  50. package/dist/memory-router/index.d.ts.map +1 -0
  51. package/dist/memory-router/index.js +122 -0
  52. package/dist/memory-router/index.js.map +1 -0
  53. package/dist/memory-router/routing-tables.d.ts +125 -0
  54. package/dist/memory-router/routing-tables.d.ts.map +1 -0
  55. package/dist/memory-router/routing-tables.js +137 -0
  56. package/dist/memory-router/routing-tables.js.map +1 -0
  57. package/dist/memory-router/select-backend.d.ts +136 -0
  58. package/dist/memory-router/select-backend.d.ts.map +1 -0
  59. package/dist/memory-router/select-backend.js +210 -0
  60. package/dist/memory-router/select-backend.js.map +1 -0
  61. package/dist/multi-stage-guardrails/index.d.ts +190 -0
  62. package/dist/multi-stage-guardrails/index.d.ts.map +1 -0
  63. package/dist/multi-stage-guardrails/index.js +186 -0
  64. package/dist/multi-stage-guardrails/index.js.map +1 -0
  65. package/dist/read-router/ReadRouter.d.ts +58 -0
  66. package/dist/read-router/ReadRouter.d.ts.map +1 -0
  67. package/dist/read-router/ReadRouter.js +91 -0
  68. package/dist/read-router/ReadRouter.js.map +1 -0
  69. package/dist/read-router/classifier.d.ts +54 -0
  70. package/dist/read-router/classifier.d.ts.map +1 -0
  71. package/dist/read-router/classifier.js +104 -0
  72. package/dist/read-router/classifier.js.map +1 -0
  73. package/dist/read-router/costs.d.ts +23 -0
  74. package/dist/read-router/costs.d.ts.map +1 -0
  75. package/dist/read-router/costs.js +51 -0
  76. package/dist/read-router/costs.js.map +1 -0
  77. package/dist/read-router/dispatcher.d.ts +33 -0
  78. package/dist/read-router/dispatcher.d.ts.map +1 -0
  79. package/dist/read-router/dispatcher.js +29 -0
  80. package/dist/read-router/dispatcher.js.map +1 -0
  81. package/dist/read-router/index.d.ts +23 -0
  82. package/dist/read-router/index.d.ts.map +1 -0
  83. package/dist/read-router/index.js +17 -0
  84. package/dist/read-router/index.js.map +1 -0
  85. package/dist/read-router/routing-tables.d.ts +85 -0
  86. package/dist/read-router/routing-tables.d.ts.map +1 -0
  87. package/dist/read-router/routing-tables.js +79 -0
  88. package/dist/read-router/routing-tables.js.map +1 -0
  89. package/dist/read-router/select-strategy.d.ts +42 -0
  90. package/dist/read-router/select-strategy.d.ts.map +1 -0
  91. package/dist/read-router/select-strategy.js +92 -0
  92. package/dist/read-router/select-strategy.js.map +1 -0
  93. package/package.json +21 -1
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @file IngestRouter.ts
3
+ * @description Top-level input-stage orchestrator that composes the
4
+ * ingest classifier and the pure {@link selectIngestStrategy} into a
5
+ * single per-content routing call.
6
+ *
7
+ * Same shape as MemoryRouter (recall-stage) so the multi-stage guardrails
8
+ * orchestrator can compose them uniformly. Decide-only and decide+dispatch
9
+ * flows are both supported.
10
+ *
11
+ * @module @framers/agentos/ingest-router/IngestRouter
12
+ */
13
+ import type { IIngestClassifier, IngestClassifierResult } from './classifier.js';
14
+ import { type IngestStrategyCostPoint } from './costs.js';
15
+ import { type IngestContentKind, type IngestRouterPreset, type IngestRoutingTable, type IngestStrategyId } from './routing-tables.js';
16
+ import { type IngestBudgetMode, type IngestRoutingDecision } from './select-strategy.js';
17
+ import type { IIngestDispatcher } from './dispatcher.js';
18
+ export interface IngestBudgetPolicy {
19
+ readonly perIngestUsd?: number;
20
+ readonly mode?: IngestBudgetMode;
21
+ }
22
+ export interface IngestRouterOptions {
23
+ readonly classifier: IIngestClassifier;
24
+ readonly preset?: IngestRouterPreset;
25
+ readonly routingTable?: IngestRoutingTable;
26
+ readonly mapping?: Partial<Record<IngestContentKind, IngestStrategyId>>;
27
+ readonly budget?: IngestBudgetPolicy;
28
+ readonly strategyCosts?: Readonly<Record<IngestStrategyId, IngestStrategyCostPoint>>;
29
+ readonly useFewShotPrompt?: boolean;
30
+ readonly dispatcher?: IIngestDispatcher<unknown, unknown>;
31
+ }
32
+ export interface IngestRouterDecideOptions {
33
+ /**
34
+ * Optional manual override of the classifier. When set, the classifier
35
+ * is NOT invoked and the routing table is consulted with this kind
36
+ * directly. Useful when the caller already knows the content kind
37
+ * (e.g., file extension determines code vs structured-data).
38
+ */
39
+ readonly manualKind?: IngestContentKind;
40
+ readonly groundTruthKind?: IngestContentKind | null;
41
+ readonly useFewShotPrompt?: boolean;
42
+ }
43
+ export interface IngestRouterDecision {
44
+ readonly classifier: IngestClassifierResult;
45
+ readonly routing: IngestRoutingDecision;
46
+ }
47
+ export interface IngestRouterDispatchedResult<TOutcome> {
48
+ readonly decision: IngestRouterDecision;
49
+ readonly outcome: TOutcome;
50
+ readonly strategy: IngestStrategyId;
51
+ }
52
+ export declare class IngestRouterDispatcherMissingError extends Error {
53
+ constructor();
54
+ }
55
+ /**
56
+ * Public input-stage orchestrator. One instance per ingest endpoint;
57
+ * reuse across content events.
58
+ */
59
+ export declare class IngestRouter {
60
+ private readonly classifier;
61
+ private readonly preset;
62
+ private readonly routingTable;
63
+ private readonly budgetPerIngestUsd;
64
+ private readonly budgetMode;
65
+ private readonly strategyCosts;
66
+ private readonly defaultUseFewShotPrompt;
67
+ private readonly dispatcher;
68
+ constructor(options: IngestRouterOptions);
69
+ decide(content: string, options?: IngestRouterDecideOptions): Promise<IngestRouterDecision>;
70
+ decideAndDispatch<TOutcome, TPayload = undefined>(content: string, dispatchPayload?: TPayload, options?: IngestRouterDecideOptions): Promise<IngestRouterDispatchedResult<TOutcome>>;
71
+ }
72
+ //# sourceMappingURL=IngestRouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IngestRouter.d.ts","sourceRoot":"","sources":["../../src/ingest-router/IngestRouter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @file IngestRouter.ts
3
+ * @description Top-level input-stage orchestrator that composes the
4
+ * ingest classifier and the pure {@link selectIngestStrategy} into a
5
+ * single per-content routing call.
6
+ *
7
+ * Same shape as MemoryRouter (recall-stage) so the multi-stage guardrails
8
+ * orchestrator can compose them uniformly. Decide-only and decide+dispatch
9
+ * flows are both supported.
10
+ *
11
+ * @module @framers/agentos/ingest-router/IngestRouter
12
+ */
13
+ import { DEFAULT_INGEST_COSTS, } from './costs.js';
14
+ import { PRESET_INGEST_TABLES, } from './routing-tables.js';
15
+ import { selectIngestStrategy, } from './select-strategy.js';
16
+ export class IngestRouterDispatcherMissingError extends Error {
17
+ constructor() {
18
+ super('IngestRouter.decideAndDispatch requires a dispatcher. ' +
19
+ 'Either pass a dispatcher in options or call `decide` and dispatch yourself.');
20
+ this.name = 'IngestRouterDispatcherMissingError';
21
+ }
22
+ }
23
+ /**
24
+ * Public input-stage orchestrator. One instance per ingest endpoint;
25
+ * reuse across content events.
26
+ */
27
+ export class IngestRouter {
28
+ constructor(options) {
29
+ this.classifier = options.classifier;
30
+ this.preset = options.preset ?? 'raw-chunks';
31
+ this.dispatcher = options.dispatcher ?? null;
32
+ const baseTable = options.routingTable ?? PRESET_INGEST_TABLES[this.preset];
33
+ if (options.mapping) {
34
+ const patched = {
35
+ ...baseTable.defaultMapping,
36
+ };
37
+ for (const key of Object.keys(options.mapping)) {
38
+ const ov = options.mapping[key];
39
+ if (ov)
40
+ patched[key] = ov;
41
+ }
42
+ this.routingTable = Object.freeze({
43
+ preset: baseTable.preset,
44
+ defaultMapping: Object.freeze(patched),
45
+ });
46
+ }
47
+ else {
48
+ this.routingTable = baseTable;
49
+ }
50
+ this.budgetPerIngestUsd = options.budget?.perIngestUsd ?? null;
51
+ this.budgetMode = options.budget?.mode ?? 'cheapest-fallback';
52
+ this.strategyCosts = options.strategyCosts ?? DEFAULT_INGEST_COSTS;
53
+ this.defaultUseFewShotPrompt = options.useFewShotPrompt ?? false;
54
+ }
55
+ async decide(content, options) {
56
+ let classifier;
57
+ if (options?.manualKind) {
58
+ classifier = {
59
+ kind: options.manualKind,
60
+ tokensIn: 0,
61
+ tokensOut: 0,
62
+ model: 'manual',
63
+ };
64
+ }
65
+ else {
66
+ const useFewShot = options?.useFewShotPrompt ?? this.defaultUseFewShotPrompt;
67
+ classifier = await this.classifier.classify(content, useFewShot ? { useFewShotPrompt: true } : undefined);
68
+ }
69
+ const routing = selectIngestStrategy({
70
+ predictedKind: classifier.kind,
71
+ groundTruthKind: options?.groundTruthKind ?? null,
72
+ config: {
73
+ table: this.routingTable,
74
+ budgetPerIngestUsd: this.budgetPerIngestUsd,
75
+ budgetMode: this.budgetMode,
76
+ strategyCosts: this.strategyCosts,
77
+ },
78
+ });
79
+ return { classifier, routing };
80
+ }
81
+ async decideAndDispatch(content, dispatchPayload, options) {
82
+ if (!this.dispatcher) {
83
+ throw new IngestRouterDispatcherMissingError();
84
+ }
85
+ const decision = await this.decide(content, options);
86
+ const dispatched = (await this.dispatcher.dispatch({
87
+ strategy: decision.routing.chosenStrategy,
88
+ content,
89
+ payload: dispatchPayload,
90
+ }));
91
+ return {
92
+ decision,
93
+ outcome: dispatched.outcome,
94
+ strategy: dispatched.strategy,
95
+ };
96
+ }
97
+ }
98
+ //# sourceMappingURL=IngestRouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IngestRouter.js","sourceRoot":"","sources":["../../src/ingest-router/IngestRouter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @file classifier.ts
3
+ * @description LLM-as-judge classifier that maps a piece of content to
4
+ * one of the six {@link IngestContentKind} values.
5
+ *
6
+ * Same shape as the memory-router classifier — deliberately so the
7
+ * multi-stage guardrails orchestrator can compose them with one mental
8
+ * model.
9
+ *
10
+ * @module @framers/agentos/ingest-router/classifier
11
+ */
12
+ import { type IngestContentKind } from './routing-tables.js';
13
+ export interface IngestClassifierLLMRequest {
14
+ readonly system: string;
15
+ readonly user: string;
16
+ readonly maxTokens: number;
17
+ readonly temperature: number;
18
+ }
19
+ export interface IngestClassifierLLMResponse {
20
+ readonly text: string;
21
+ readonly tokensIn: number;
22
+ readonly tokensOut: number;
23
+ readonly model: string;
24
+ }
25
+ export interface IIngestClassifierLLM {
26
+ invoke(request: IngestClassifierLLMRequest): Promise<IngestClassifierLLMResponse>;
27
+ }
28
+ export interface IngestClassifierClassifyOptions {
29
+ /** Use the few-shot prompt variant (more accurate on ambiguous content). */
30
+ readonly useFewShotPrompt?: boolean;
31
+ }
32
+ export interface IngestClassifierResult {
33
+ readonly kind: IngestContentKind;
34
+ readonly tokensIn: number;
35
+ readonly tokensOut: number;
36
+ readonly model: string;
37
+ }
38
+ export interface IIngestClassifier {
39
+ classify(content: string, options?: IngestClassifierClassifyOptions): Promise<IngestClassifierResult>;
40
+ }
41
+ export declare const INGEST_CLASSIFIER_SYSTEM_PROMPT = "You are classifying a piece of content into one of six ingest kinds for memory storage.\n\nReturn ONLY the kind token (no explanation, no quotes, no punctuation).\n\nKinds:\n- short-conversation: 1-3 turns of chat dialog. Examples: a one-message Q&A, a brief support exchange.\n- long-conversation: extended chat sessions across many turns. Examples: a 50-turn coding conversation, a 30-turn customer support thread.\n- long-article: prose document over ~500 words. Examples: a blog post, a research paper section, a long email.\n- code: source code, configuration files, schemas. Examples: a TypeScript module, a SQL migration, a JSON schema.\n- structured-data: tabular or JSON-style records. Examples: a CSV, a JSON list of records, a database export.\n- multimodal: content that includes images, video frames, or audio. Examples: a PDF with figures, a presentation slide.";
42
+ export declare const INGEST_CLASSIFIER_SYSTEM_PROMPT_FEWSHOT = "You are classifying a piece of content into one of six ingest kinds for memory storage.\n\nReturn ONLY the kind token (no explanation, no quotes, no punctuation).\n\nKinds:\n- short-conversation: 1-3 turns of chat dialog.\n- long-conversation: extended chat sessions across many turns.\n- long-article: prose document over ~500 words.\n- code: source code, configuration files, schemas.\n- structured-data: tabular or JSON-style records.\n- multimodal: content that includes images, video frames, or audio.\n\nExamples:\n\nContent: \"user: hi\\nassistant: hi! how can I help?\"\nKind: short-conversation\n\nContent: \"[3000 words of a research paper introduction]\"\nKind: long-article\n\nContent: \"export function fibonacci(n: number): number { return n < 2 ? n : fibonacci(n-1) + fibonacci(n-2); }\"\nKind: code\n\nContent: \"[CSV with 50 rows of user records]\"\nKind: structured-data\n\nContent: \"[40 turns of a customer-support thread]\"\nKind: long-conversation\n\nContent: \"[image bytes + caption text]\"\nKind: multimodal";
43
+ export declare const SAFE_INGEST_FALLBACK_KIND: IngestContentKind;
44
+ export declare function normalizeIngestClassifierOutput(raw: string): string;
45
+ export declare function parseIngestClassifierOutput(raw: string): IngestContentKind;
46
+ export interface LLMIngestClassifierOptions {
47
+ readonly llm: IIngestClassifierLLM;
48
+ readonly maxTokens?: number;
49
+ /**
50
+ * Maximum content characters to forward to the classifier. Most ingest
51
+ * decisions can be made from the first ~1k chars (kind detection
52
+ * doesn't require the full body). Default 1000.
53
+ */
54
+ readonly maxContentChars?: number;
55
+ }
56
+ export declare class LLMIngestClassifier implements IIngestClassifier {
57
+ private readonly llm;
58
+ private readonly maxTokens;
59
+ private readonly maxContentChars;
60
+ constructor(options: LLMIngestClassifierOptions);
61
+ classify(content: string, options?: IngestClassifierClassifyOptions): Promise<IngestClassifierResult>;
62
+ }
63
+ //# sourceMappingURL=classifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classifier.d.ts","sourceRoot":"","sources":["../../src/ingest-router/classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AAM7B,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CACJ,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,2BAA2B,CAAC,CAAC;CACzC;AAMD,MAAM,WAAW,+BAA+B;IAC9C,4EAA4E;IAC5E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CACN,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,+BAA+B,GACxC,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACpC;AAMD,eAAO,MAAM,+BAA+B,g3BAU4E,CAAC;AAEzH,eAAO,MAAM,uCAAuC,6gCA8BnC,CAAC;AAElB,eAAO,MAAM,yBAAyB,EAAE,iBAAwC,CAAC;AAEjF,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAcnE;AAED,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAY1E;AAMD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,GAAG,EAAE,oBAAoB,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,qBAAa,mBAAoB,YAAW,iBAAiB;IAC3D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAuB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAE7B,OAAO,EAAE,0BAA0B;IAMzC,QAAQ,CACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,+BAA+B,GACxC,OAAO,CAAC,sBAAsB,CAAC;CAqBnC"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * @file classifier.ts
3
+ * @description LLM-as-judge classifier that maps a piece of content to
4
+ * one of the six {@link IngestContentKind} values.
5
+ *
6
+ * Same shape as the memory-router classifier — deliberately so the
7
+ * multi-stage guardrails orchestrator can compose them with one mental
8
+ * model.
9
+ *
10
+ * @module @framers/agentos/ingest-router/classifier
11
+ */
12
+ import { INGEST_CONTENT_KINDS, } from './routing-tables.js';
13
+ // ============================================================================
14
+ // Prompts
15
+ // ============================================================================
16
+ export const INGEST_CLASSIFIER_SYSTEM_PROMPT = `You are classifying a piece of content into one of six ingest kinds for memory storage.
17
+
18
+ Return ONLY the kind token (no explanation, no quotes, no punctuation).
19
+
20
+ Kinds:
21
+ - short-conversation: 1-3 turns of chat dialog. Examples: a one-message Q&A, a brief support exchange.
22
+ - long-conversation: extended chat sessions across many turns. Examples: a 50-turn coding conversation, a 30-turn customer support thread.
23
+ - long-article: prose document over ~500 words. Examples: a blog post, a research paper section, a long email.
24
+ - code: source code, configuration files, schemas. Examples: a TypeScript module, a SQL migration, a JSON schema.
25
+ - structured-data: tabular or JSON-style records. Examples: a CSV, a JSON list of records, a database export.
26
+ - multimodal: content that includes images, video frames, or audio. Examples: a PDF with figures, a presentation slide.`;
27
+ export const INGEST_CLASSIFIER_SYSTEM_PROMPT_FEWSHOT = `You are classifying a piece of content into one of six ingest kinds for memory storage.
28
+
29
+ Return ONLY the kind token (no explanation, no quotes, no punctuation).
30
+
31
+ Kinds:
32
+ - short-conversation: 1-3 turns of chat dialog.
33
+ - long-conversation: extended chat sessions across many turns.
34
+ - long-article: prose document over ~500 words.
35
+ - code: source code, configuration files, schemas.
36
+ - structured-data: tabular or JSON-style records.
37
+ - multimodal: content that includes images, video frames, or audio.
38
+
39
+ Examples:
40
+
41
+ Content: "user: hi\\nassistant: hi! how can I help?"
42
+ Kind: short-conversation
43
+
44
+ Content: "[3000 words of a research paper introduction]"
45
+ Kind: long-article
46
+
47
+ Content: "export function fibonacci(n: number): number { return n < 2 ? n : fibonacci(n-1) + fibonacci(n-2); }"
48
+ Kind: code
49
+
50
+ Content: "[CSV with 50 rows of user records]"
51
+ Kind: structured-data
52
+
53
+ Content: "[40 turns of a customer-support thread]"
54
+ Kind: long-conversation
55
+
56
+ Content: "[image bytes + caption text]"
57
+ Kind: multimodal`;
58
+ export const SAFE_INGEST_FALLBACK_KIND = 'short-conversation';
59
+ export function normalizeIngestClassifierOutput(raw) {
60
+ const lines = raw.split('\n');
61
+ let firstLine = '';
62
+ for (const ln of lines) {
63
+ if (ln.trim().length > 0) {
64
+ firstLine = ln;
65
+ break;
66
+ }
67
+ }
68
+ let cleaned = firstLine.trim().toLowerCase();
69
+ cleaned = cleaned.replace(/^(kind|category|type|answer|label|class)\s*[:\-=]\s*/, '');
70
+ cleaned = cleaned.replace(/^["'`]+|["'`]+$/g, '');
71
+ cleaned = cleaned.replace(/[.,;!?]+$/g, '');
72
+ return cleaned.trim();
73
+ }
74
+ export function parseIngestClassifierOutput(raw) {
75
+ const cleaned = normalizeIngestClassifierOutput(raw);
76
+ for (const token of INGEST_CONTENT_KINDS) {
77
+ if (cleaned === token ||
78
+ cleaned.startsWith(`${token} `) ||
79
+ cleaned.startsWith(`${token}\n`)) {
80
+ return token;
81
+ }
82
+ }
83
+ return SAFE_INGEST_FALLBACK_KIND;
84
+ }
85
+ export class LLMIngestClassifier {
86
+ constructor(options) {
87
+ this.llm = options.llm;
88
+ this.maxTokens = options.maxTokens ?? 16;
89
+ this.maxContentChars = options.maxContentChars ?? 1000;
90
+ }
91
+ async classify(content, options) {
92
+ const system = options?.useFewShotPrompt
93
+ ? INGEST_CLASSIFIER_SYSTEM_PROMPT_FEWSHOT
94
+ : INGEST_CLASSIFIER_SYSTEM_PROMPT;
95
+ const truncated = content.slice(0, this.maxContentChars);
96
+ const user = `Content: ${truncated}\n\nKind:`;
97
+ const response = await this.llm.invoke({
98
+ system,
99
+ user,
100
+ maxTokens: this.maxTokens,
101
+ temperature: 0,
102
+ });
103
+ return {
104
+ kind: parseIngestClassifierOutput(response.text),
105
+ tokensIn: response.tokensIn,
106
+ tokensOut: response.tokensOut,
107
+ model: response.model,
108
+ };
109
+ }
110
+ }
111
+ //# sourceMappingURL=classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classifier.js","sourceRoot":"","sources":["../../src/ingest-router/classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,oBAAoB,GAErB,MAAM,qBAAqB,CAAC;AAiD7B,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E,MAAM,CAAC,MAAM,+BAA+B,GAAG;;;;;;;;;;wHAUyE,CAAC;AAEzH,MAAM,CAAC,MAAM,uCAAuC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8BtC,CAAC;AAElB,MAAM,CAAC,MAAM,yBAAyB,GAAsB,oBAAoB,CAAC;AAEjF,MAAM,UAAU,+BAA+B,CAAC,GAAW;IACzD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,SAAS,GAAG,EAAE,CAAC;YACf,MAAM;QACR,CAAC;IACH,CAAC;IACD,IAAI,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7C,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,sDAAsD,EAAE,EAAE,CAAC,CAAC;IACtF,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;IAClD,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,GAAW;IACrD,MAAM,OAAO,GAAG,+BAA+B,CAAC,GAAG,CAAC,CAAC;IACrD,KAAK,MAAM,KAAK,IAAI,oBAAoB,EAAE,CAAC;QACzC,IACE,OAAO,KAAK,KAAK;YACjB,OAAO,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC;YAC/B,OAAO,CAAC,UAAU,CAAC,GAAG,KAAK,IAAI,CAAC,EAChC,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,yBAAyB,CAAC;AACnC,CAAC;AAiBD,MAAM,OAAO,mBAAmB;IAK9B,YAAY,OAAmC;QAC7C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,OAAe,EACf,OAAyC;QAEzC,MAAM,MAAM,GAAG,OAAO,EAAE,gBAAgB;YACtC,CAAC,CAAC,uCAAuC;YACzC,CAAC,CAAC,+BAA+B,CAAC;QACpC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,YAAY,SAAS,WAAW,CAAC;QAE9C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YACrC,MAAM;YACN,IAAI;YACJ,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,WAAW,EAAE,CAAC;SACf,CAAC,CAAC;QAEH,OAAO;YACL,IAAI,EAAE,2BAA2B,CAAC,QAAQ,CAAC,IAAI,CAAC;YAChD,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,KAAK,EAAE,QAAQ,CAAC,KAAK;SACtB,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @file costs.ts
3
+ * @description Cost-points for ingest strategies.
4
+ *
5
+ * Unlike retrieval where Phase B measurements give us per-category
6
+ * accuracy + cost data, ingest cost is dominated by LLM-call counts at
7
+ * write time and is much more workload-dependent (a long-article may
8
+ * have 1 summarize call; a long-conversation may have 30 observation
9
+ * extraction calls). The numbers below are illustrative averages; for
10
+ * production-budget enforcement, consumers should override with measured
11
+ * values from their own workload.
12
+ *
13
+ * @module @framers/agentos/ingest-router/costs
14
+ */
15
+ import type { IngestStrategyId } from './routing-tables.js';
16
+ /**
17
+ * Cost-point for one ingest strategy. The router uses this to apply
18
+ * budget constraints + pick a cheaper fallback when a strategy doesn't
19
+ * fit a per-ingest USD ceiling.
20
+ */
21
+ export interface IngestStrategyCostPoint {
22
+ readonly strategy: IngestStrategyId;
23
+ /** Average USD per ingest event (one session / one document). */
24
+ readonly avgCostPerIngest: number;
25
+ /**
26
+ * Average latency per ingest in milliseconds. For short content this
27
+ * is roughly proportional to the number of LLM calls.
28
+ */
29
+ readonly avgLatencyMs: number;
30
+ /**
31
+ * Free-form label describing what this strategy actually writes
32
+ * (chunks, summarized chunks, observations, fact triples, etc.).
33
+ * Useful for telemetry + dashboards.
34
+ */
35
+ readonly outputDescription: string;
36
+ }
37
+ export declare const RAW_CHUNKS_COST: IngestStrategyCostPoint;
38
+ export declare const SUMMARIZED_COST: IngestStrategyCostPoint;
39
+ export declare const OBSERVATIONAL_COST: IngestStrategyCostPoint;
40
+ export declare const FACT_GRAPH_COST: IngestStrategyCostPoint;
41
+ export declare const HYBRID_COST: IngestStrategyCostPoint;
42
+ export declare const SKIP_COST: IngestStrategyCostPoint;
43
+ /**
44
+ * Default cost-points registry. Override per workload by passing a
45
+ * custom map to {@link IngestRouter} at construction.
46
+ */
47
+ export declare const DEFAULT_INGEST_COSTS: Readonly<Record<IngestStrategyId, IngestStrategyCostPoint>>;
48
+ //# sourceMappingURL=costs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"costs.d.ts","sourceRoot":"","sources":["../../src/ingest-router/costs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,iEAAiE;IACjE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC;AAED,eAAO,MAAM,eAAe,EAAE,uBAKD,CAAC;AAE9B,eAAO,MAAM,eAAe,EAAE,uBAKD,CAAC;AAE9B,eAAO,MAAM,kBAAkB,EAAE,uBAKJ,CAAC;AAE9B,eAAO,MAAM,eAAe,EAAE,uBAKD,CAAC;AAE9B,eAAO,MAAM,WAAW,EAAE,uBAKG,CAAC;AAE9B,eAAO,MAAM,SAAS,EAAE,uBAKK,CAAC;AAE9B;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CACzC,MAAM,CAAC,gBAAgB,EAAE,uBAAuB,CAAC,CAQjD,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @file costs.ts
3
+ * @description Cost-points for ingest strategies.
4
+ *
5
+ * Unlike retrieval where Phase B measurements give us per-category
6
+ * accuracy + cost data, ingest cost is dominated by LLM-call counts at
7
+ * write time and is much more workload-dependent (a long-article may
8
+ * have 1 summarize call; a long-conversation may have 30 observation
9
+ * extraction calls). The numbers below are illustrative averages; for
10
+ * production-budget enforcement, consumers should override with measured
11
+ * values from their own workload.
12
+ *
13
+ * @module @framers/agentos/ingest-router/costs
14
+ */
15
+ export const RAW_CHUNKS_COST = Object.freeze({
16
+ strategy: 'raw-chunks',
17
+ avgCostPerIngest: 0.0001, // embedding-only
18
+ avgLatencyMs: 200,
19
+ outputDescription: 'raw turns/chunks with embeddings',
20
+ });
21
+ export const SUMMARIZED_COST = Object.freeze({
22
+ strategy: 'summarized',
23
+ avgCostPerIngest: 0.005, // one LLM summarize call per session/document
24
+ avgLatencyMs: 1500,
25
+ outputDescription: 'session/document summary prefixed to every chunk',
26
+ });
27
+ export const OBSERVATIONAL_COST = Object.freeze({
28
+ strategy: 'observational',
29
+ avgCostPerIngest: 0.020, // multi-call observation extraction
30
+ avgLatencyMs: 6000,
31
+ outputDescription: 'structured observation log replacing raw turns',
32
+ });
33
+ export const FACT_GRAPH_COST = Object.freeze({
34
+ strategy: 'fact-graph',
35
+ avgCostPerIngest: 0.015, // triple extraction
36
+ avgLatencyMs: 4500,
37
+ outputDescription: 'fact triples + entity-relation graph',
38
+ });
39
+ export const HYBRID_COST = Object.freeze({
40
+ strategy: 'hybrid',
41
+ avgCostPerIngest: 0.030, // raw + summarized + observational
42
+ avgLatencyMs: 8000,
43
+ outputDescription: 'parallel raw-chunks + summarized + observational outputs',
44
+ });
45
+ export const SKIP_COST = Object.freeze({
46
+ strategy: 'skip',
47
+ avgCostPerIngest: 0,
48
+ avgLatencyMs: 0,
49
+ outputDescription: 'content discarded; nothing written to memory',
50
+ });
51
+ /**
52
+ * Default cost-points registry. Override per workload by passing a
53
+ * custom map to {@link IngestRouter} at construction.
54
+ */
55
+ export const DEFAULT_INGEST_COSTS = Object.freeze({
56
+ 'raw-chunks': RAW_CHUNKS_COST,
57
+ summarized: SUMMARIZED_COST,
58
+ observational: OBSERVATIONAL_COST,
59
+ 'fact-graph': FACT_GRAPH_COST,
60
+ hybrid: HYBRID_COST,
61
+ skip: SKIP_COST,
62
+ });
63
+ //# sourceMappingURL=costs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"costs.js","sourceRoot":"","sources":["../../src/ingest-router/costs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA0BH,MAAM,CAAC,MAAM,eAAe,GAA4B,MAAM,CAAC,MAAM,CAAC;IACpE,QAAQ,EAAE,YAAqB;IAC/B,gBAAgB,EAAE,MAAM,EAAE,iBAAiB;IAC3C,YAAY,EAAE,GAAG;IACjB,iBAAiB,EAAE,kCAAkC;CACtD,CAA4B,CAAC;AAE9B,MAAM,CAAC,MAAM,eAAe,GAA4B,MAAM,CAAC,MAAM,CAAC;IACpE,QAAQ,EAAE,YAAqB;IAC/B,gBAAgB,EAAE,KAAK,EAAE,8CAA8C;IACvE,YAAY,EAAE,IAAI;IAClB,iBAAiB,EAAE,kDAAkD;CACtE,CAA4B,CAAC;AAE9B,MAAM,CAAC,MAAM,kBAAkB,GAA4B,MAAM,CAAC,MAAM,CAAC;IACvE,QAAQ,EAAE,eAAwB;IAClC,gBAAgB,EAAE,KAAK,EAAE,oCAAoC;IAC7D,YAAY,EAAE,IAAI;IAClB,iBAAiB,EAAE,gDAAgD;CACpE,CAA4B,CAAC;AAE9B,MAAM,CAAC,MAAM,eAAe,GAA4B,MAAM,CAAC,MAAM,CAAC;IACpE,QAAQ,EAAE,YAAqB;IAC/B,gBAAgB,EAAE,KAAK,EAAE,oBAAoB;IAC7C,YAAY,EAAE,IAAI;IAClB,iBAAiB,EAAE,sCAAsC;CAC1D,CAA4B,CAAC;AAE9B,MAAM,CAAC,MAAM,WAAW,GAA4B,MAAM,CAAC,MAAM,CAAC;IAChE,QAAQ,EAAE,QAAiB;IAC3B,gBAAgB,EAAE,KAAK,EAAE,mCAAmC;IAC5D,YAAY,EAAE,IAAI;IAClB,iBAAiB,EAAE,0DAA0D;CAC9E,CAA4B,CAAC;AAE9B,MAAM,CAAC,MAAM,SAAS,GAA4B,MAAM,CAAC,MAAM,CAAC;IAC9D,QAAQ,EAAE,MAAe;IACzB,gBAAgB,EAAE,CAAC;IACnB,YAAY,EAAE,CAAC;IACf,iBAAiB,EAAE,8CAA8C;CAClE,CAA4B,CAAC;AAE9B;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAE7B,MAAM,CAAC,MAAM,CAAC;IAChB,YAAY,EAAE,eAAe;IAC7B,UAAU,EAAE,eAAe;IAC3B,aAAa,EAAE,kBAAkB;IACjC,YAAY,EAAE,eAAe;IAC7B,MAAM,EAAE,WAAW;IACnB,IAAI,EAAE,SAAS;CAChB,CAAC,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @file dispatcher.ts
3
+ * @description Backend-execution layer for {@link IngestRouter}.
4
+ *
5
+ * Same routing-table-of-functions pattern as memory-router's
6
+ * {@link FunctionMemoryDispatcher}. Caller registers per-strategy
7
+ * executors at construction; dispatcher picks the right one per call.
8
+ *
9
+ * @module @framers/agentos/ingest-router/dispatcher
10
+ */
11
+ import type { IngestStrategyId } from './routing-tables.js';
12
+ export type IngestStrategyExecutor<TOutcome, TPayload = undefined> = (content: string, payload: TPayload) => Promise<TOutcome>;
13
+ export interface IngestDispatchArgs<TPayload = undefined> {
14
+ readonly strategy: IngestStrategyId;
15
+ readonly content: string;
16
+ readonly payload?: TPayload;
17
+ }
18
+ export interface IngestDispatchResult<TOutcome> {
19
+ readonly outcome: TOutcome;
20
+ readonly strategy: IngestStrategyId;
21
+ }
22
+ export interface IIngestDispatcher<TOutcome = unknown, TPayload = unknown> {
23
+ dispatch(args: IngestDispatchArgs<TPayload>): Promise<IngestDispatchResult<TOutcome>>;
24
+ }
25
+ export declare class UnsupportedIngestStrategyError extends Error {
26
+ readonly strategy: IngestStrategyId;
27
+ constructor(strategy: IngestStrategyId);
28
+ }
29
+ export type IngestStrategyRegistry<TOutcome, TPayload> = Partial<Record<IngestStrategyId, IngestStrategyExecutor<TOutcome, TPayload>>>;
30
+ export declare class FunctionIngestDispatcher<TOutcome, TPayload = undefined> implements IIngestDispatcher<TOutcome, TPayload> {
31
+ private readonly registry;
32
+ constructor(registry: IngestStrategyRegistry<TOutcome, TPayload>);
33
+ dispatch(args: IngestDispatchArgs<TPayload>): Promise<IngestDispatchResult<TOutcome>>;
34
+ }
35
+ //# sourceMappingURL=dispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/ingest-router/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,MAAM,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,IAAI,CACnE,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,QAAQ,KACd,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvB,MAAM,WAAW,kBAAkB,CAAC,QAAQ,GAAG,SAAS;IACtD,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB,CAAC,QAAQ;IAC5C,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,GAAG,OAAO;IACvE,QAAQ,CACN,IAAI,EAAE,kBAAkB,CAAC,QAAQ,CAAC,GACjC,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC;CAC5C;AAED,qBAAa,8BAA+B,SAAQ,KAAK;aAC3B,QAAQ,EAAE,gBAAgB;gBAA1B,QAAQ,EAAE,gBAAgB;CAOvD;AAED,MAAM,MAAM,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,IAAI,OAAO,CAC9D,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CACrE,CAAC;AAEF,qBAAa,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAClE,YAAW,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAEhD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6C;gBAE1D,QAAQ,EAAE,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAI1D,QAAQ,CACZ,IAAI,EAAE,kBAAkB,CAAC,QAAQ,CAAC,GACjC,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;CAQ3C"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @file dispatcher.ts
3
+ * @description Backend-execution layer for {@link IngestRouter}.
4
+ *
5
+ * Same routing-table-of-functions pattern as memory-router's
6
+ * {@link FunctionMemoryDispatcher}. Caller registers per-strategy
7
+ * executors at construction; dispatcher picks the right one per call.
8
+ *
9
+ * @module @framers/agentos/ingest-router/dispatcher
10
+ */
11
+ export class UnsupportedIngestStrategyError extends Error {
12
+ constructor(strategy) {
13
+ super(`IngestDispatcher: strategy '${strategy}' is not registered. ` +
14
+ `Supply an executor for this strategy at construction.`);
15
+ this.strategy = strategy;
16
+ this.name = 'UnsupportedIngestStrategyError';
17
+ }
18
+ }
19
+ export class FunctionIngestDispatcher {
20
+ constructor(registry) {
21
+ this.registry = registry;
22
+ }
23
+ async dispatch(args) {
24
+ const exec = this.registry[args.strategy];
25
+ if (!exec) {
26
+ throw new UnsupportedIngestStrategyError(args.strategy);
27
+ }
28
+ const outcome = await exec(args.content, args.payload);
29
+ return { outcome, strategy: args.strategy };
30
+ }
31
+ }
32
+ //# sourceMappingURL=dispatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/ingest-router/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA0BH,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IACvD,YAA4B,QAA0B;QACpD,KAAK,CACH,+BAA+B,QAAQ,uBAAuB;YAC5D,uDAAuD,CAC1D,CAAC;QAJwB,aAAQ,GAAR,QAAQ,CAAkB;QAKpD,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;IAC/C,CAAC;CACF;AAMD,MAAM,OAAO,wBAAwB;IAKnC,YAAY,QAAoD;QAC9D,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,IAAkC;QAElC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,8BAA8B,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAmB,CAAC,CAAC;QACnE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC9C,CAAC;CACF"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * AgentOS IngestRouter Module
3
+ *
4
+ * Input-stage LLM-as-judge orchestrator for memory ingest. Sibling of
5
+ * {@link MemoryRouter} (recall-stage), {@link QueryRouter} (Q&A-stage),
6
+ * and the output-stage guardrails. Together they form the agentos
7
+ * multi-stage guardrails pattern.
8
+ *
9
+ * Where MemoryRouter picks the recall architecture for a query,
10
+ * IngestRouter picks the storage architecture for incoming content. The
11
+ * choice affects what's STORED, which downstream MemoryRouter then queries.
12
+ *
13
+ * **Architecture Overview:**
14
+ * ```
15
+ * Content stream
16
+ * │
17
+ * ▼
18
+ * ┌────────────────────────────────────────────────┐
19
+ * │ IngestRouter │
20
+ * │ classify content → pick strategy → store │
21
+ * └────────────────────────────────────────────────┘
22
+ * │ │ │
23
+ * ▼ ▼ ▼
24
+ * raw-chunks summarized observational
25
+ * fact-graph hybrid skip
26
+ * ```
27
+ *
28
+ * @module @framers/agentos/ingest-router
29
+ */
30
+ export type { IngestContentKind, IngestStrategyId, IngestRouterPreset, IngestRoutingTable, } from './routing-tables.js';
31
+ export { INGEST_CONTENT_KINDS } from './routing-tables.js';
32
+ export type { IngestStrategyCostPoint } from './costs.js';
33
+ export type { IngestBudgetMode, IngestRouterConfig, IngestRoutingDecision, } from './select-strategy.js';
34
+ export type { IIngestClassifier, IIngestClassifierLLM, IngestClassifierLLMRequest, IngestClassifierLLMResponse, IngestClassifierClassifyOptions, IngestClassifierResult, LLMIngestClassifierOptions, } from './classifier.js';
35
+ export type { IIngestDispatcher, IngestDispatchArgs, IngestDispatchResult, IngestStrategyExecutor, IngestStrategyRegistry, } from './dispatcher.js';
36
+ export type { IngestBudgetPolicy, IngestRouterOptions, IngestRouterDecideOptions, IngestRouterDecision, IngestRouterDispatchedResult, } from './IngestRouter.js';
37
+ export { RAW_CHUNKS_TABLE, SUMMARIZED_TABLE, OBSERVATIONAL_TABLE, HYBRID_TABLE, PRESET_INGEST_TABLES, } from './routing-tables.js';
38
+ export { RAW_CHUNKS_COST, SUMMARIZED_COST, OBSERVATIONAL_COST, FACT_GRAPH_COST, HYBRID_COST, SKIP_COST, DEFAULT_INGEST_COSTS, } from './costs.js';
39
+ export { selectIngestStrategy, IngestRouterUnknownKindError, IngestRouterBudgetExceededError, } from './select-strategy.js';
40
+ export { INGEST_CLASSIFIER_SYSTEM_PROMPT, INGEST_CLASSIFIER_SYSTEM_PROMPT_FEWSHOT, SAFE_INGEST_FALLBACK_KIND, LLMIngestClassifier, normalizeIngestClassifierOutput, parseIngestClassifierOutput, } from './classifier.js';
41
+ export { FunctionIngestDispatcher, UnsupportedIngestStrategyError, } from './dispatcher.js';
42
+ export { IngestRouter, IngestRouterDispatcherMissingError, } from './IngestRouter.js';
43
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ingest-router/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,EAC1B,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,SAAS,EACT,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,+BAA+B,GAChC,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,+BAA+B,EAC/B,uCAAuC,EACvC,yBAAyB,EACzB,mBAAmB,EACnB,+BAA+B,EAC/B,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,wBAAwB,EACxB,8BAA8B,GAC/B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,YAAY,EACZ,kCAAkC,GACnC,MAAM,mBAAmB,CAAC"}