@exellix/ai-tasks 8.4.2 → 8.4.3

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 (94) hide show
  1. package/.docs/DOWNSTREAM_ENV.md +42 -0
  2. package/.docs/FEEDBACK_TO_CLIENT_DOWNSTREAM_FIXES.md +64 -0
  3. package/.docs/INTERMEDIATE_STEPS.md +82 -0
  4. package/.docs/activity-structure.md +31 -0
  5. package/.docs/ai-task-ai-scoping-spec.md +338 -0
  6. package/.docs/ai-tasks-model-profile-aliases-7x.md +74 -0
  7. package/.docs/blockers-and-issues.md +346 -0
  8. package/.docs/building-runTask-sdk.md +659 -0
  9. package/.docs/building-skill-execution-orchestrator.md +968 -0
  10. package/.docs/code-used-before/run-task.txt +39 -0
  11. package/.docs/code-used-before/task-executor.ts.old +57 -0
  12. package/.docs/code-used-before/test-run-task.ts.old +42 -0
  13. package/.docs/code-used-before/types.txt +23 -0
  14. package/.docs/env-ready-policy.md +40 -0
  15. package/.docs/flow-io/flow-README.md +76 -0
  16. package/.docs/flow-io/narrix.md +124 -0
  17. package/.docs/flow-io/web-scoping.md +135 -0
  18. package/.docs/flow-io/xynthesis-post.md +154 -0
  19. package/.docs/flow-io/xynthesis-pre.md +181 -0
  20. package/.docs/gap-analysis.md +201 -0
  21. package/.docs/integration-facts-ai-tasks.md +109 -0
  22. package/.docs/investigation/ai-skills.md +170 -0
  23. package/.docs/investigation/external-packages-assignments.md +66 -0
  24. package/.docs/investigation/integration-summary.md +20 -0
  25. package/.docs/investigation/narrix-catalox.md +29 -0
  26. package/.docs/investigation/workplan-close-graph-engine-gaps.md +101 -0
  27. package/.docs/logging-stack.md +30 -0
  28. package/.docs/memory-narrix-adapter-developer-guide.md +402 -0
  29. package/.docs/memory-narrix-adapter-requirements.md +112 -0
  30. package/.docs/narrix-context-consumption-gap.md +184 -0
  31. package/.docs/narrix-context-downstream-report.md +30 -0
  32. package/.docs/narrix-ingest-and-packs-library-spec.md +240 -0
  33. package/.docs/narrix-record-input-current-design.md +48 -0
  34. package/.docs/pacakge.md +48 -0
  35. package/.docs/possible-components/README.md +11 -0
  36. package/.docs/possible-components/integration/README.md +10 -0
  37. package/.docs/possible-components/integration/gaps-when-merging.md +16 -0
  38. package/.docs/possible-components/integration/platform.md +54 -0
  39. package/.docs/possible-components/integration/reintegrate-into-ai-tasks.md +26 -0
  40. package/.docs/possible-components/integration/roadmap-and-checklists.md +54 -0
  41. package/.docs/possible-components/post-component/README.md +18 -0
  42. package/.docs/possible-components/post-component/builder-guide.md +175 -0
  43. package/.docs/possible-components/post-component/gaps-and-artifacts.md +52 -0
  44. package/.docs/possible-components/post-component/handler-audit.md +47 -0
  45. package/.docs/possible-components/post-component/handler-polish.md +41 -0
  46. package/.docs/possible-components/post-component/unified-protocol.md +59 -0
  47. package/.docs/possible-components/pre-component/README.md +22 -0
  48. package/.docs/possible-components/pre-component/builder-guide.md +127 -0
  49. package/.docs/possible-components/pre-component/gaps-and-artifacts.md +35 -0
  50. package/.docs/possible-components/pre-component/handler-ai-scoping.md +45 -0
  51. package/.docs/possible-components/pre-component/handler-narrix-preprocessor.md +49 -0
  52. package/.docs/possible-components/pre-component/handler-narrix-system2.md +35 -0
  53. package/.docs/possible-components/pre-component/handler-synthesized-context.md +65 -0
  54. package/.docs/possible-components/pre-component/handler-web-scope.md +29 -0
  55. package/.docs/possible-components/pre-component/unified-protocol.md +89 -0
  56. package/.docs/prefer-openrouter-routing-policy.md +132 -0
  57. package/.docs/questions-for-ai-skills.md +123 -0
  58. package/.docs/realtime-narrixing-gap-analysis.md +40 -0
  59. package/.docs/realtime-narrixing.md +433 -0
  60. package/.docs/run-context-object.md +32 -0
  61. package/.docs/session-id-usage.md +26 -0
  62. package/.docs/skill-library-spec.md +249 -0
  63. package/.docs/synthesized-context-strategy-spec.md +906 -0
  64. package/.docs/upstream-issue/2026-03-21_woroces-ai-tasks_ISSUE-006_web-scope-question-from-cni-entity.md +46 -0
  65. package/.docs/web-scopper-embed.md +93 -0
  66. package/.docs/xynthesis-wiring-and-io.md +12 -0
  67. package/README.md +15 -13
  68. package/dist/index.d.ts +2 -1
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +1 -1
  71. package/dist/index.js.map +1 -1
  72. package/dist/internal/runPostStepLlmCall.d.ts.map +1 -1
  73. package/dist/internal/runPostStepLlmCall.js +4 -2
  74. package/dist/internal/runPostStepLlmCall.js.map +1 -1
  75. package/dist/invocation/resolveProfileInvocationRouting.js +2 -2
  76. package/dist/invocation/resolveProfileInvocationRouting.js.map +1 -1
  77. package/dist/utils/aiProfileModelFormat.d.ts +2 -2
  78. package/dist/utils/aiProfileModelFormat.js +2 -2
  79. package/dist/utils/aiProfilesCatalog.d.ts +16 -0
  80. package/dist/utils/aiProfilesCatalog.d.ts.map +1 -0
  81. package/dist/utils/aiProfilesCatalog.js +23 -0
  82. package/dist/utils/aiProfilesCatalog.js.map +1 -0
  83. package/dist/utils/resolveAiProfileModel.d.ts +2 -2
  84. package/dist/utils/resolveAiProfileModel.d.ts.map +1 -1
  85. package/dist/utils/resolveAiProfileModel.js +5 -5
  86. package/dist/utils/resolveAiProfileModel.js.map +1 -1
  87. package/dist/utils/routeModelConfigSlots.d.ts +3 -1
  88. package/dist/utils/routeModelConfigSlots.d.ts.map +1 -1
  89. package/dist/utils/routeModelConfigSlots.js +2 -1
  90. package/dist/utils/routeModelConfigSlots.js.map +1 -1
  91. package/documenations/upstream-feature-requests/README.md +2 -2
  92. package/documenations/upstream-feature-requests/ai-tasks-wrap-up-after-upstream.md +5 -2
  93. package/documenations/upstream-feature-requests/xynthesis-orchestrator-invoke-contract-4.2.md +2 -2
  94. package/package.json +2 -1
@@ -0,0 +1,127 @@
1
+ # Pre-Task component — **builder guide** (single entry for implementation)
2
+
3
+ Use this file plus the linked handler specs. **Full** platform rules (Activix field shapes, identity merge algorithm): [`../integration/platform.md`](../integration/platform.md).
4
+
5
+ ---
6
+
7
+ ## 1. What you are building
8
+
9
+ A **Pre-Task engine** that runs **before MAIN** and returns:
10
+
11
+ - Possibly updated `jobMemory` / `taskMemory` / `executionMemory` / `input`
12
+ - Optional **`contextMarkdown`** override for the MAIN skill prompt
13
+ - Optional **`synthesizedContext`** artifact on `executionMemory`
14
+ - **`intermediateSteps`** for observability
15
+
16
+ **Protocol:** [`unified-protocol.md`](unified-protocol.md).
17
+
18
+ ---
19
+
20
+ ## 2. Stack (minimum you must honor)
21
+
22
+ | Topic | Rule |
23
+ |-------|------|
24
+ | LLM calls | **aifunctions-js** (`ask` / compatible client). Not a separate ai-gateway product API. |
25
+ | Synthesized-context step | **@athenices/xynthesis** for templates, modes, validation; **SynthesisInvoker** calls aifunctions-js. |
26
+ | Observability | **Activix** phase records where the host enables it; top-level **`identity`** on every record per `docs/activix-identity.md`. |
27
+ | Correlation | Prefer **`correlationId === taskId`** for one run. |
28
+
29
+ ---
30
+
31
+ ## 3. NPM dependencies (pin to tested versions from `@woroces/ai-tasks`)
32
+
33
+ | Package | Role in pre paths |
34
+ |---------|-------------------|
35
+ | `aifunctions-js` | All generative calls (scoping, System-2, synthesis invoker). |
36
+ | `@athenices/xynthesis` | Synthesized-context PRE handler. |
37
+ | `@woroces/ai-skills` | `enrichMemoriesWithScoping`, `resolveRawTemplate`, executor (host). |
38
+ | `@woroces/memory-narrix-adapter` | `adaptMemoryToNarrixInput` (narrix preprocessor). |
39
+ | `@narrices/narrix-*` | Ingest, adapters, runner, packs, web-scoper (see `package.json` of ai-tasks). |
40
+ | `@xronoces/activix` | Phase recording (with host wrapper). |
41
+
42
+ Also used indirectly: `handlebars` (if you render web scope templates in-host).
43
+
44
+ ---
45
+
46
+ ## 4. Host contract (skills / task runtime)
47
+
48
+ The pre engine **does not** replace the skills client. The host must provide:
49
+
50
+ | Capability | Used by |
51
+ |------------|---------|
52
+ | `enrichMemoriesWithScoping(skillKey, "task", memoryBundle)` | Synthesis PRE, direct-path enrich (same as today). |
53
+ | `resolveRawTemplate(skillKey, "instructions" \| "prompt")` → raw markdown | Structured synthesis + template cores. |
54
+ | Optional: same client’s `generateContextMarkdown` / executor | After pre returns, MAIN still runs in host. |
55
+
56
+ ---
57
+
58
+ ## 5. Request fields this engine reads (`RunTaskRequest`)
59
+
60
+ | Field | Handler |
61
+ |-------|---------|
62
+ | `narrix?: NarrixPreProcessorConfig` | [`handler-narrix-preprocessor.md`](handler-narrix-preprocessor.md) |
63
+ | `executionPipeline` with PRE `synthesized-context` | [`handler-synthesized-context.md`](handler-synthesized-context.md) |
64
+ | `aiScoping?: AIScopingInstruction[]` | [`handler-ai-scoping.md`](handler-ai-scoping.md) |
65
+ | `includeContextInPrompt`, `taskMemory`, `jobMemory`, `executionMemory`, `skillKey`, `input`, `identity`, `jobId`, `agentId` | Multiple |
66
+
67
+ **Note:** `executionType: narrix-then-direct` + `narrixInput` is a **different** flow (Narrix then MAIN with `taskMemory.narrix`); it still uses `narrixRunHandler` and is **host-orchestrated** in `task-sdk.ts`. If your pre package only covers “pipeline + scoping + narrix preprocessor”, document whether `narrix-then-direct` stays in the host.
68
+
69
+ ---
70
+
71
+ ## 6. Environment variables (pre-relevant)
72
+
73
+ | Variable | Handler / area |
74
+ |----------|----------------|
75
+ | `AI_SCOPING_MODEL`, `AI_SCOPING_CONCURRENCY`, `AI_SCOPING_TIMEOUT_MS` | AI scoping |
76
+ | `SYNTHESIS_MODEL`, `SYNTHESIS_TIMEOUT_MS`, `SYNTHESIS_MAX_OUTPUT_LENGTH` | Synthesis PRE |
77
+ | `NARRIX_SYSTEM2_MODE`, `NARRIX_SYSTEM2_MODEL`, `NARRIX_SYSTEM2_MAX_ITERATIONS`, `NARRIX_SYSTEM2_ENABLE_WRITES`, `NARRIX_SYSTEM2_SAVE_ARTIFACTS`, `NARRIX_SYSTEM2_ARTIFACT_DIR`, … | System-2 |
78
+ | `TAVILY_API_KEY` | Web scope (default search) |
79
+ | `MONGO_LOGS_DB` | Default `bindingDefaultsDb` merged into `execution` (current SDK behavior) |
80
+
81
+ Centralize in one config module in your package.
82
+
83
+ ---
84
+
85
+ ## 7. Source file manifest (current `ai-tasks`)
86
+
87
+ Copy or depend on these paths when extracting:
88
+
89
+ | Path | Notes |
90
+ |------|--------|
91
+ | `src/aiScoping/*` | Scoping + `validateAiScoping.ts` |
92
+ | `src/internal/runLlmTextCall.ts` | Shared LLM primitive |
93
+ | `src/synthesis/resolveSourceMaterial.ts`, `synthesisGatewayCompat.ts`, `index.ts` | Synthesis wiring + xynthesis re-exports |
94
+ | `src/narrix/**` except tests | Narrix run, web scoper, system2, context markdown builders |
95
+ | `src/utils/jsonPaths.ts` | `getByPath` for scoping sources |
96
+ | `src/types/task-types.ts` | Types listed in handler docs |
97
+
98
+ ---
99
+
100
+ ## 8. Definition of done (acceptance)
101
+
102
+ - [ ] Handlers run in order: narrix preprocessor (if any) → pipeline PRE synthesized-context (if any) → (host) enrich → ai scoping (if any).
103
+ - [ ] Synthesis: markdown + structured modes behave per [`handler-synthesized-context.md`](handler-synthesized-context.md); `fallbackToDirect` respected.
104
+ - [ ] Scoping: parallel bounded concurrency; missing paths skipped; validation before LLM.
105
+ - [ ] Web scope: never throws to caller; `webContext` optional on `executionMemory`.
106
+ - [ ] System-2: PatchPlan JSON validated; iteration cap enforced.
107
+ - [ ] Activix + `identity` on each recorded phase when host passes client.
108
+ - [ ] Test hooks: scoping / synthesis / llmPlan / web scoper injectable.
109
+
110
+ ---
111
+
112
+ ## 9. Types (canonical source)
113
+
114
+ Implementations should align with **`src/types/task-types.ts`**: `AIScopingInstruction`, `AIScopedItem`, `SynthesisConfig`, `SynthesizedContextArtifact`, `ContextSourcePolicy`, `WebEvidenceConfig`, `ExecutionStep`, `NarrixPreProcessorConfig`, `IntermediateStep`, and pipeline constants (`SYNTHESIZED_CONTEXT`). Re-export or depend on a shared types package when splitting repos.
115
+
116
+ ---
117
+
118
+ ## 10. Read next
119
+
120
+ 1. [`unified-protocol.md`](unified-protocol.md)
121
+ 2. [`handler-narrix-preprocessor.md`](handler-narrix-preprocessor.md)
122
+ 3. [`handler-synthesized-context.md`](handler-synthesized-context.md)
123
+ 4. [`handler-ai-scoping.md`](handler-ai-scoping.md)
124
+ 5. [`handler-web-scope.md`](handler-web-scope.md)
125
+ 6. [`handler-narrix-system2.md`](handler-narrix-system2.md)
126
+ 7. [`gaps-and-artifacts.md`](gaps-and-artifacts.md)
127
+ 8. Merge / shared checklist: [`../integration/roadmap-and-checklists.md`](../integration/roadmap-and-checklists.md) Phase B, [`../integration/reintegrate-into-ai-tasks.md`](../integration/reintegrate-into-ai-tasks.md)
@@ -0,0 +1,35 @@
1
+ # Pre-Task component — gaps, code, templates
2
+
3
+ What is **missing, external, or optional to add** when packaging the pre engine. **Behavior, env tables, dependencies, acceptance:** [`builder-guide.md`](builder-guide.md).
4
+
5
+ ## Code modules (current `ai-tasks` anchors)
6
+
7
+ | Area | Paths / packages | Note |
8
+ |------|------------------|------|
9
+ | AI scoping | `src/aiScoping/*` (incl. `validateAiScoping.ts`) | Depends on `src/internal/runLlmTextCall.ts`. |
10
+ | Synthesis source wiring | `src/synthesis/resolveSourceMaterial.ts`, `synthesisGatewayCompat.ts` | Re-export surface: `src/synthesis/index.ts` → **@athenices/xynthesis**. |
11
+ | Narrix pre + web | `src/narrix/*` (large), `task-sdk` orchestration | System-1 ingest lives largely in **external** Narrix packages. |
12
+ | System-2 | `src/narrix/system2/*` | Tied to `runLlmTextCall`. |
13
+ | Types | `src/types/task-types.ts` (`AIScoping*`, `SynthesisConfig`, pipeline types) | May need a shared types package when extracting. |
14
+
15
+ ## Templates & assets
16
+
17
+ | Asset | Status in repo | Action for standalone pre package |
18
+ |-------|----------------|-------------------------------------|
19
+ | Synthesis markdown templates | Loaded via **@athenices/xynthesis** `loadSynthesisTemplates()` | Confirm templates ship **inside** xynthesis or **vendor** copies into the pre package; audit/polish disk templates belong in **post** spec only. |
20
+ | Skill instructions/prompt | **@woroces/ai-skills** `resolveRawTemplate` | Pre component needs a **host callback**; not bundled in pre-only package. |
21
+ | AI scoping | **No** separate disk template — prompts inline in `runScopingCall.ts` | Optional: externalize to `templates/pre/scoping-system.md` for versioning. |
22
+ | Narrix System-2 | System prompt **inline** in `llmPlan.ts` | Optional: externalize for tuning without code change. |
23
+
24
+ ## Environment variables
25
+
26
+ Canonical table: [`builder-guide.md`](builder-guide.md) §6.
27
+
28
+ ## Tests / DI hooks to preserve
29
+
30
+ `setScopingGateway`, `setSynthesisInvoker` / `setSynthesisGateway`, `setLlmPlanGateway`, `setWebScoperForTesting` — or equivalent constructor injection in a new package.
31
+
32
+ ## Open decisions
33
+
34
+ - Whether **narrix-preprocessor** ships inside pre package or stays a **peer** dependency.
35
+ - Single **Activix** wrapper module shared with post (owned under integration / shared lib).
@@ -0,0 +1,45 @@
1
+ # Handler: AI memory scoping (`direct.ai-scoping`)
2
+
3
+ > **Platform:** LLM + Activix + `identity` — [`../integration/platform.md`](../integration/platform.md).
4
+
5
+ ## Purpose
6
+
7
+ Before MAIN, optionally turn memory slices into concise text. Each instruction is one LLM call over **only** resolved source content; results merge into `input.aiScoped[]`.
8
+
9
+ ## Trigger (current repo)
10
+
11
+ - `RunTaskRequest.aiScoping?: AIScopingInstruction[]`
12
+ - After enrich, before `executor.execute` in `_executeDirect` (`src/core/task-sdk.ts`).
13
+ - Code: `src/aiScoping/runAiScoping.ts`, `runScopingCall.ts`.
14
+
15
+ ## Inputs
16
+
17
+ | Field | Notes |
18
+ |--------|--------|
19
+ | Bundle | `jobMemory` / `taskMemory` / `executionMemory`; paths via `getByPath`. |
20
+ | Instructions | `source`, `instructions` (NL), `targetToken` per item. |
21
+ | Concurrency / timeout | Defaults 5 workers, 30s/item; env `AI_SCOPING_*`. |
22
+
23
+ Skipped if source path missing (no error). `validateAiScoping` before calls.
24
+
25
+ ## Single call (`runScopingCall`)
26
+
27
+ - Fixed system: use only source, no invention, plain text, no markdown fences.
28
+ - User: `Instructions:\n…\n\nSource content:\n…` (serialized value).
29
+ - `runLlmTextCall`: temp 0.2, maxTokens 2048; test hook `setScopingGateway`.
30
+
31
+ ## Orchestration (`runAiScoping`)
32
+
33
+ Bounded parallel workers; failures → omit that item (tolerant).
34
+
35
+ ## Output
36
+
37
+ `AIScopedItem[]` → merged into object `input` as `aiScoped`.
38
+
39
+ ## Non-goals
40
+
41
+ Not full RAG; chunks are independent. No automatic memory writeback.
42
+
43
+ ## Types
44
+
45
+ `AIScopingInstruction`, `AIScopedItem` — `src/types/task-types.ts`.
@@ -0,0 +1,49 @@
1
+ # Handler: Narrix preprocessor (`narrix-preprocessor`)
2
+
3
+ > **Platform:** [`../integration/platform.md`](../integration/platform.md).
4
+ > **Sub-steps:** [`handler-web-scope.md`](handler-web-scope.md), [`handler-narrix-system2.md`](handler-narrix-system2.md) (inside `narrixRunHandler`).
5
+
6
+ ## Purpose
7
+
8
+ When `RunTaskRequest.narrix` is set, adapt task memory to a **Narrix run input**, execute **`narrixRunHandler`** (local skill `skills/skill.local:narrixRun`), attach enrichment to **`executionMemory`** and **`jobMemory`**, optionally fetch **web evidence**.
9
+
10
+ ## Trigger (current repo)
11
+
12
+ - `request.narrix` present → phase `narrix` in `task-sdk.ts` before local-task dispatch and pipeline.
13
+ - Uses `adaptMemoryToNarrixInput` from `@woroces/memory-narrix-adapter` with path preferences (`executionMemory.input.raw`, `jobMemory.currentRecord`, …).
14
+ - Failure to adapt → **throw** (strict). Narrix run `ok: false` → **throw**.
15
+
16
+ ## Config (`NarrixPreProcessorConfig`) — fields builders need
17
+
18
+ | Field | Role |
19
+ |-------|------|
20
+ | `datasetId` | Required. |
21
+ | `attachToField` | Default `_narrix`; where attachment lives on `executionMemory`. |
22
+ | `deterministicSort` | Default true (narrative ordering). |
23
+ | `enableWebScope` | After success, call web scoper → `executionMemory.webContext`. |
24
+ | `webScopeTemplates`, `webScopeQuestionTemplate`, `webScopeObjects`, `webScoping` | Web query shaping (see `NarrixPreProcessorConfig` in `task-types.ts`). |
25
+ | `engineConfigPath`, `packsRoot`, `assumptionsPolicy` | Reserved / future. |
26
+
27
+ Full interface: `src/types/task-types.ts`.
28
+
29
+ ## Success path (summary)
30
+
31
+ 1. `adaptMemoryToNarrixInput(...)` → `narrixInput`.
32
+ 2. `narrixRunHandler({ input, ctx })` with skill/job/graph ids from request.
33
+ 3. `buildNarrixAttachment(success)` → store under `executionMemory[attachToField]` and `jobMemory._narrix` (current behavior).
34
+ 4. If `enableWebScope`: `resolveWebScopeQuestionAndTemplates` + `runWebScope` → merge `webContext` (lenient).
35
+
36
+ ## Related execution mode
37
+
38
+ **`narrix-then-direct`** uses resolved `narrixInput` + `narrixRunHandler` + `applyNarrixScope` and writes **`taskMemory.narrix`** — different injection shape. Implement either in the same package behind flags or document as **host-only** if out of scope.
39
+
40
+ ## Code anchors
41
+
42
+ - `src/core/task-sdk.ts` (narrix block)
43
+ - `src/narrix/task.ts` (`narrixRunHandler`)
44
+ - `src/narrix/buildNarrixAttachment.ts`, `buildWebScopeScopeInput`, `webScoper.ts`
45
+ - `src/activix/phaseTracking.ts` (`withPhaseRecord`)
46
+
47
+ ## Dependencies
48
+
49
+ Narrix ingest/runner/packs packages; `NARRIX_DISABLED` / flags in `src/narrix/flags.ts` may disable behavior.
@@ -0,0 +1,35 @@
1
+ # Sub-handler: Narrix System-2 LLM patch plan
2
+
3
+ > **Platform:** [`../integration/platform.md`](../integration/platform.md).
4
+
5
+ ## Purpose
6
+
7
+ After Narrix System-1, optionally detect gaps and call an LLM for **PatchPlan** JSON (routing/schema actions), apply patches, optionally re-run System-1.
8
+
9
+ ## Trigger (current repo)
10
+
11
+ - `narrixRunHandler` → `runWithSystem2` (`src/narrix/system2/runWithSystem2.ts`)
12
+ - LLM: `llmPlan` (`src/narrix/system2/llmPlan.ts`)
13
+ - Env/options: `NARRIX_SYSTEM2_MODE`, `maxIterations`, `enableWrites`, `model`, etc.
14
+
15
+ ## LLM I/O
16
+
17
+ - User content from `buildSystem2Input(input, result, gapHints)`.
18
+ - System: PatchPlan JSON only; allowed action types defined in code (`rememberDatasetPackRouting`, …).
19
+ - Parse: `extractJsonFromText` + `validatePatchPlan`.
20
+
21
+ ## Invocation
22
+
23
+ `runLlmTextCall`: temp 0.2, maxTokens 8192; `setLlmPlanGateway` for tests.
24
+
25
+ ## Post-LLM
26
+
27
+ `applyPatchPlan`, optional `writeArtifacts`, rerun loop under `maxIterations`.
28
+
29
+ ## Non-goals
30
+
31
+ Not a general agent; closed action set. Does not replace System-1 ingest (external packages).
32
+
33
+ ## Dependencies (repo)
34
+
35
+ `src/narrix/system2/*`, `src/internal/runLlmTextCall.ts`
@@ -0,0 +1,65 @@
1
+ # Handler: synthesized context (`pipeline.synthesized-context`)
2
+
3
+ > **Platform:** **@athenices/xynthesis** for synthesis contracts; **aifunctions-js** inside `SynthesisInvoker`; Activix + `identity` — [`../integration/platform.md`](../integration/platform.md) §1b.
4
+
5
+ ## Purpose
6
+
7
+ PRE pipeline step: build markdown **context** for MAIN from memory, Narrix attachment, optional web evidence, and rendered skill templates. Modes: **markdown** completion vs **structured** synthesis (cores + validation).
8
+
9
+ ## Trigger (current repo)
10
+
11
+ - `executionPipeline`: `{ phase: "pre", type: "synthesized-context", config?: SynthesisConfig }`
12
+ - Requires `includeContextInPrompt === true` or `config.autoEnableContext === true`
13
+ - `WorexClientTasks._runSynthesizedContextPreStep` in `src/core/task-sdk.ts`
14
+
15
+ ## Orchestration (high level)
16
+
17
+ 1. Merge `executionMemory` into `jobMemory.execution` (incl. `bindingDefaultsDb` default).
18
+ 2. `enrichMemoriesWithScoping(skillKey, "task", memoryBundle)`.
19
+ 3. Cleanse `execution` for prompts.
20
+ 4. Narrix-shaped attachment from `executionMemory[attachToField]` or `taskMemory.narrix`.
21
+ 5. `buildSynthesizerInputMaterial` (**@athenices/xynthesis** + host `resolveSourceMaterial*`).
22
+ 6. `getRenderedTemplates` (skill raw templates + placeholders).
23
+ 7. Branch: markdown vs structured (below).
24
+ 8. Optional `SynthesizedContextArtifact` on `executionMemory.synthesizedContext`.
25
+
26
+ `fallbackToDirect` → empty context instead of throw on materialization failure (when enabled).
27
+
28
+ ## Mode A — Markdown
29
+
30
+ - `loadSynthesisTemplates`, `buildSynthesisSystemPrompt`, `runSynthesisCall` from **@athenices/xynthesis**.
31
+ - Defaults: model from config → `SYNTHESIS_MODEL` → `gpt-5-nano`; timeout `SYNTHESIS_TIMEOUT_MS` / 30_000.
32
+
33
+ ## Mode B — Structured
34
+
35
+ - Parts: `localMarkdown` / `supportingMarkdown`; `resolveSynthesisQuestion`; `discoverTemplateCores`.
36
+ - Custom path: `getContextSynthesizer()` if set; else `runStructuredSynthesisGatewayCall`.
37
+ - Output: `buildSynthesizedContextMarkdown(payload)`.
38
+
39
+ ## Xynthesis vs aifunctions-js (single definition)
40
+
41
+ | Layer | Role |
42
+ |-------|------|
43
+ | **@athenices/xynthesis** | Templates, modes, validation, artifact types, `setSynthesisInvoker`. |
44
+ | **aifunctions-js** | Implement invoker with `client.ask` (or shared helper). |
45
+
46
+ ## Testing / migration
47
+
48
+ - `setSynthesisInvoker` (preferred).
49
+ - Legacy: `src/synthesis/synthesisGatewayCompat.ts` → `setSynthesisGateway` for `invoke`-shaped mocks only.
50
+
51
+ ## Downstream
52
+
53
+ MAIN uses `overrideContext`; `synthesisContextAuthoritative` blocks Narrix/web fill-in when empty. POST audit/polish use captured context markdown.
54
+
55
+ ## Config surface
56
+
57
+ `SynthesisConfig`: `modelConfig`, `timeoutMs`, `maxOutputLength`, `synthesisInputStrategy`, `contextSourcePolicy`, `memoryPaths`, `webEvidence`, `fallbackToDirect`, structured limits, prompt overrides, mode.
58
+
59
+ ## Risks
60
+
61
+ Structured mode needs `resolveRawTemplate` / registry; missing templates → errors unless fallback.
62
+
63
+ ## Repo anchors
64
+
65
+ `src/synthesis/resolveSourceMaterial.ts`, `src/synthesis/synthesisGatewayCompat.ts`, `src/synthesis/index.ts` (re-exports xynthesis).
@@ -0,0 +1,29 @@
1
+ # Sub-step: Web scope / evidence (Narrix add-on)
2
+
3
+ > **Platform:** Activix + `identity` for phases; no generative LLM here — [`../integration/platform.md`](../integration/platform.md).
4
+
5
+ ## Purpose
6
+
7
+ After a successful Narrix pre-processor run, optionally fetch search-backed evidence into `executionMemory.webContext` for synthesis / MAIN.
8
+
9
+ ## Trigger (current repo)
10
+
11
+ - `request.narrix.enableWebScope === true`
12
+ - `resolveWebScopeQuestionAndTemplates` + `runWebScope` in `src/narrix/webScoper.ts`, called from `task-sdk.ts`.
13
+
14
+ ## Stack
15
+
16
+ - `createWebScoper` + `createSearchAdapter` (Tavily + `TAVILY_API_KEY` default).
17
+ - Errors → `{ available: false, reason: "error", error }` (no throw).
18
+
19
+ ## Testing
20
+
21
+ `setWebScoperForTesting`, `resetWebScoperSingleton`.
22
+
23
+ ## Relation to synthesis
24
+
25
+ `SynthesisConfig.webEvidence` / `resolveSourceMaterial*` may consume `webContext` from memory.
26
+
27
+ ## Dependencies
28
+
29
+ `@narrices/narrix-web-scoper`, `@narrices/search-adapter`
@@ -0,0 +1,89 @@
1
+ # Pre-Task component — unified protocol
2
+
3
+ > **Scope:** Target architecture only; not a mandate to change `ai-tasks` code until you choose to.
4
+ > **Shared platform (aifunctions-js, Activix, identity, Xynthesis):** single source of truth is [`../integration/platform.md`](../integration/platform.md).
5
+
6
+ ---
7
+
8
+ ## Goal
9
+
10
+ One **Pre-Task engine** that:
11
+
12
+ - Accepts a standard **input envelope** (task request, skills client, memory, optional Activix + correlation + identity).
13
+ - Runs an **ordered chain** of handlers sharing one protocol.
14
+ - Produces **patches** to request/memory/input, optional **context override** for MAIN, optional **synthesis artifact**, and **intermediate steps**.
15
+
16
+ ---
17
+
18
+ ## Handler protocol (conceptual)
19
+
20
+ ```ts
21
+ type PreHandlerId =
22
+ | "narrix-preprocessor"
23
+ | "pipeline.synthesized-context"
24
+ | "direct.ai-scoping";
25
+
26
+ interface PreHandlerContext {
27
+ request: RunTaskRequest;
28
+ identity?: Record<string, unknown>;
29
+ memoryBundle?: unknown;
30
+ skillsClient?: unknown;
31
+ correlationId?: string;
32
+ activix?: unknown;
33
+ prior: {
34
+ contextMarkdownOverride?: string;
35
+ synthesisContextAuthoritative?: boolean;
36
+ executionMemoryPatch?: Record<string, unknown>;
37
+ };
38
+ }
39
+
40
+ interface PreHandlerResult {
41
+ ok: boolean;
42
+ patches?: {
43
+ jobMemory?: Record<string, unknown>;
44
+ taskMemory?: Record<string, unknown>;
45
+ executionMemory?: Record<string, unknown>;
46
+ input?: unknown;
47
+ };
48
+ contextMarkdownOverride?: string;
49
+ synthesisContextAuthoritative?: boolean;
50
+ artifact?: unknown;
51
+ intermediateSteps?: IntermediateStep[];
52
+ error?: { code: string; message: string };
53
+ }
54
+
55
+ interface PreTaskHandler {
56
+ id: PreHandlerId;
57
+ order: number;
58
+ shouldRun(ctx: PreHandlerContext): boolean;
59
+ run(ctx: PreHandlerContext): Promise<PreHandlerResult>;
60
+ }
61
+ ```
62
+
63
+ **Composition:** engine merges `patches` in order, concatenates `intermediateSteps`, forwards `prior` to the next handler. Per-handler failure policy (strict vs tolerant) is part of each handler spec.
64
+
65
+ ---
66
+
67
+ ## Built-in handlers (index)
68
+
69
+ | Handler id | Trigger (today) | Detail doc |
70
+ |------------|-----------------|------------|
71
+ | `narrix-preprocessor` | `RunTaskRequest.narrix` | [`handler-narrix-preprocessor.md`](handler-narrix-preprocessor.md); web scope [`handler-web-scope.md`](handler-web-scope.md). |
72
+ | `pipeline.synthesized-context` | `executionPipeline` PRE `synthesized-context` | [`handler-synthesized-context.md`](handler-synthesized-context.md) (**@athenices/xynthesis**). |
73
+ | `direct.ai-scoping` | `RunTaskRequest.aiScoping[]` | [`handler-ai-scoping.md`](handler-ai-scoping.md). |
74
+
75
+ **Narrix System-2** (`llmPlan`) is a **sub-phase** of narrix (or a nested handler with the same result type). Spec: [`handler-narrix-system2.md`](handler-narrix-system2.md).
76
+
77
+ ---
78
+
79
+ ## Canonical execution order
80
+
81
+ 1. `narrix-preprocessor` (if `request.narrix`)
82
+ 2. Pipeline PRE steps — `pipeline.synthesized-context` when present
83
+ 3. MAIN prep inside direct: memory enrich → `direct.ai-scoping` → executor
84
+
85
+ ---
86
+
87
+ ## Extension
88
+
89
+ New pre feature ⇒ new `PreTaskHandler` + register. For synthesis-like behavior, prefer **Xynthesis** (see platform doc §1b) instead of parallel prompt systems.
@@ -0,0 +1,132 @@
1
+ # `PREFER_OPENROUTER` routing policy (Exellix stack)
2
+
3
+ Normative contract for **OpenRouter vs vendor-direct** model routing across `@exellix/ai-tasks`, `@exellix/graph-engine`, graphs-studio, and `@x12i/ai-profiles` consumers.
4
+
5
+ ## Summary
6
+
7
+ | Env / API field | Status | Meaning |
8
+ |-----------------|--------|---------|
9
+ | **`PREFER_OPENROUTER`** | **Current** | Operator **preference**: use OpenRouter when an OpenRouter API key is available. |
10
+ | **`USE_OPENROUTER`** | **Deprecated** | Legacy name — read only as fallback when `PREFER_OPENROUTER` is unset. Remove from new code and docs. |
11
+ | **`preferOpenRouter`** | **Current** (API) | Same semantics as env; use on `resolveInvocationPlan({ policy })` and model-resolution options. |
12
+ | **`useOpenRouter`** | **Deprecated** (API) | Accepted temporarily for backward compatibility; map to `preferOpenRouter`. |
13
+
14
+ **Vendor API keys** (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, …) do **not** change this policy. They are used only when effective routing is **direct**. To force vendor-direct routing, set `PREFER_OPENROUTER=false`.
15
+
16
+ ---
17
+
18
+ ## Decision table (effective routing)
19
+
20
+ After resolving `preferOpenRouter` (explicit → env → default **`true`**):
21
+
22
+ | `preferOpenRouter` | `OPENROUTER_API_KEY` / `OPEN_ROUTER_KEY` | **Effective routing** | Wire model id (example) |
23
+ |--------------------|--------------------------------------------|------------------------|-------------------------|
24
+ | `false` | (any) | **direct** | `anthropic/claude-sonnet-4-5` |
25
+ | `true` | present | **openrouter** | `openrouter/anthropic/claude-sonnet-4.5` |
26
+ | `true` | absent | **direct** (fallback) + warning | `anthropic/claude-sonnet-4-5` |
27
+
28
+ This replaces the old **`USE_OPENROUTER=true` without key → still plan OpenRouter** behavior. **Prefer** means “use OpenRouter when you *can*”; missing key → honest direct fallback.
29
+
30
+ ---
31
+
32
+ ## Environment
33
+
34
+ ```env
35
+ # Prefer OpenRouter when OPENROUTER_API_KEY is set (default when omitted)
36
+ PREFER_OPENROUTER=true
37
+
38
+ # Force vendor-direct for all phases (MAIN + PRE/POST resolution)
39
+ # PREFER_OPENROUTER=false
40
+
41
+ OPENROUTER_API_KEY=sk-or-...
42
+ ANTHROPIC_API_KEY=sk-ant-... # used only when effective routing is direct
43
+ ```
44
+
45
+ **Deprecated (do not set in new deployments):**
46
+
47
+ ```env
48
+ USE_OPENROUTER=true # → read as PREFER_OPENROUTER if PREFER_OPENROUTER unset
49
+ ```
50
+
51
+ ---
52
+
53
+ ## API (`@exellix/ai-tasks`)
54
+
55
+ ```ts
56
+ import { resolveInvocationPlan } from "@exellix/ai-tasks";
57
+
58
+ const plan = await resolveInvocationPlan({
59
+ profiles: {
60
+ preActionModel: "cheap",
61
+ skillModel: "cyber@default",
62
+ postActionModel: "cheap",
63
+ },
64
+ policy: {
65
+ preferOpenRouter: true,
66
+ openrouterApiKeyPresent: !!process.env.OPENROUTER_API_KEY,
67
+ },
68
+ });
69
+ ```
70
+
71
+ Policy fields on `resolveInvocationPlan`, `resolveProfileInvocationRouting`, and `resolveModelReference`:
72
+
73
+ - **`preferOpenRouter`** — operator preference (see decision table).
74
+ - **`openrouterApiKeyPresent`** — optional snapshot; defaults to env detection in-process.
75
+ - **`useOpenRouter`** — deprecated alias for `preferOpenRouter`.
76
+
77
+ Internal mapping to `@x12i/ai-profiles` (until that package renames its option):
78
+
79
+ ```ts
80
+ resolveAIProfile(profile, {
81
+ useOpenRouter: effectiveUseOpenRouter, // from resolvePreferOpenRouterPolicy()
82
+ });
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Per-phase behavior (`runTask`)
88
+
89
+ All phases (PRE / MAIN / POST) use the **same** `resolvePreferOpenRouterPolicy()` snapshot at plan and execute time.
90
+
91
+ | Phase | Consumer | Notes |
92
+ |-------|----------|-------|
93
+ | PRE / POST | `@exellix/xynthesis` | Alias on wire; xynthesis resolves via ai-profiles with same effective routing. |
94
+ | MAIN (skill) | `@exellix/ai-skills` | Concrete model id on wire; must include `openrouter/` prefix when effective routing is openrouter. |
95
+
96
+ Plan output: trust **`routing`** + **`engineLabel`**, not model-id prefix alone.
97
+
98
+ ---
99
+
100
+ ## Migration checklist (other components)
101
+
102
+ ### graphs-studio / BFF
103
+
104
+ - [ ] Rename env reads: `USE_OPENROUTER` → `PREFER_OPENROUTER` (keep deprecated fallback one release).
105
+ - [ ] POST `/api/exellix/invocation-plan` body: `policy.preferOpenRouter` (stop sending `useOpenRouter`).
106
+ - [ ] Simulate Engine layer: call `resolveInvocationPlan` only; do not re-derive from choices matrix.
107
+ - [ ] Update UI copy: “prefers OpenRouter when key present” vs “always OpenRouter”.
108
+
109
+ ### `@exellix/graph-engine`
110
+
111
+ - [ ] Pass `policy: { preferOpenRouter, openrouterApiKeyPresent }` into `resolveInvocationPlan` before execute.
112
+ - [ ] Thread same snapshot into `runTask` policy (when execute parity lands on request env).
113
+ - [ ] Stop documenting `USE_OPENROUTER` in graph runbooks.
114
+
115
+ ### `@x12i/ai-profiles` (upstream)
116
+
117
+ - [ ] Add `preferOpenRouter` option + `readPreferOpenRouterFromEnv()` mirroring this policy.
118
+ - [ ] Deprecate `useOpenRouter` / `USE_OPENROUTER` with fallback read.
119
+ - [ ] Document that **`prefer`** falls back to direct when OpenRouter key absent.
120
+
121
+ ### `@exellix/xynthesis`
122
+
123
+ - [ ] Replace `defaultResolveAiProfileOptions()` env wiring to use `PREFER_OPENROUTER`.
124
+ - [ ] Funcx OpenRouter client: align with effective routing fallback when key missing.
125
+
126
+ ---
127
+
128
+ ## Related
129
+
130
+ - [`.docs/ai-tasks-model-profile-aliases-7x.md`](ai-tasks-model-profile-aliases-7x.md) — profile slots on `RunTaskRequest`
131
+ - `src/invocation/preferOpenRouterPolicy.ts` — implementation in ai-tasks
132
+ - `src/invocation/resolveInvocationPlan.ts` — pre-run plan API