ai-runtime-engine 1.1.0

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 (269) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/LICENSE +15 -0
  3. package/README.md +489 -0
  4. package/dist/artifacts/artifacts.d.ts +28 -0
  5. package/dist/artifacts/artifacts.js +46 -0
  6. package/dist/benchmark/benchmark.d.ts +23 -0
  7. package/dist/benchmark/benchmark.js +40 -0
  8. package/dist/cli/cli.d.ts +6 -0
  9. package/dist/cli/cli.js +161 -0
  10. package/dist/cli/commands/cleanup.d.ts +47 -0
  11. package/dist/cli/commands/cleanup.js +96 -0
  12. package/dist/cli/commands/config.d.ts +8 -0
  13. package/dist/cli/commands/config.js +28 -0
  14. package/dist/cli/commands/doctor.d.ts +57 -0
  15. package/dist/cli/commands/doctor.js +86 -0
  16. package/dist/cli/commands/executions.d.ts +9 -0
  17. package/dist/cli/commands/executions.js +25 -0
  18. package/dist/cli/commands/info.d.ts +43 -0
  19. package/dist/cli/commands/info.js +53 -0
  20. package/dist/cli/commands/init.d.ts +5 -0
  21. package/dist/cli/commands/init.js +75 -0
  22. package/dist/cli/commands/inspect.d.ts +16 -0
  23. package/dist/cli/commands/inspect.js +60 -0
  24. package/dist/cli/commands/phase2.d.ts +22 -0
  25. package/dist/cli/commands/phase2.js +83 -0
  26. package/dist/cli/commands/route.d.ts +14 -0
  27. package/dist/cli/commands/route.js +49 -0
  28. package/dist/cli/commands/run.d.ts +11 -0
  29. package/dist/cli/commands/run.js +37 -0
  30. package/dist/cli/commands/setup.d.ts +34 -0
  31. package/dist/cli/commands/setup.js +104 -0
  32. package/dist/cli/commands/skills.d.ts +28 -0
  33. package/dist/cli/commands/skills.js +48 -0
  34. package/dist/cli/commands/test.d.ts +7 -0
  35. package/dist/cli/commands/test.js +29 -0
  36. package/dist/cli/context.d.ts +12 -0
  37. package/dist/cli/context.js +16 -0
  38. package/dist/cli/interactive/repl.d.ts +6 -0
  39. package/dist/cli/interactive/repl.js +45 -0
  40. package/dist/cli/interactive/session.d.ts +36 -0
  41. package/dist/cli/interactive/session.js +356 -0
  42. package/dist/cli/prompt.d.ts +6 -0
  43. package/dist/cli/prompt.js +18 -0
  44. package/dist/cli/render.d.ts +7 -0
  45. package/dist/cli/render.js +14 -0
  46. package/dist/comparison/analysis.d.ts +46 -0
  47. package/dist/comparison/analysis.js +177 -0
  48. package/dist/comparison/comparator.d.ts +46 -0
  49. package/dist/comparison/comparator.js +270 -0
  50. package/dist/comparison/comparison.d.ts +140 -0
  51. package/dist/comparison/comparison.js +9 -0
  52. package/dist/comparison/render.d.ts +7 -0
  53. package/dist/comparison/render.js +66 -0
  54. package/dist/config/defaults.d.ts +52 -0
  55. package/dist/config/defaults.js +56 -0
  56. package/dist/config/load.d.ts +17 -0
  57. package/dist/config/load.js +50 -0
  58. package/dist/config/providerDefaults.d.ts +17 -0
  59. package/dist/config/providerDefaults.js +61 -0
  60. package/dist/config/schema.d.ts +9 -0
  61. package/dist/config/schema.js +78 -0
  62. package/dist/context/budget.d.ts +13 -0
  63. package/dist/context/budget.js +17 -0
  64. package/dist/context/compiler.d.ts +61 -0
  65. package/dist/context/compiler.js +125 -0
  66. package/dist/context/tokens.d.ts +19 -0
  67. package/dist/context/tokens.js +38 -0
  68. package/dist/conversations/conversations.d.ts +38 -0
  69. package/dist/conversations/conversations.js +64 -0
  70. package/dist/core/capabilities/evidence.d.ts +40 -0
  71. package/dist/core/capabilities/evidence.js +102 -0
  72. package/dist/core/capabilities/overlay.d.ts +15 -0
  73. package/dist/core/capabilities/overlay.js +0 -0
  74. package/dist/core/capabilities/taxonomy.d.ts +19 -0
  75. package/dist/core/capabilities/taxonomy.js +25 -0
  76. package/dist/core/fallback/errors.d.ts +30 -0
  77. package/dist/core/fallback/errors.js +80 -0
  78. package/dist/core/fallback/fallback.d.ts +40 -0
  79. package/dist/core/fallback/fallback.js +82 -0
  80. package/dist/core/fallback/retryPolicy.d.ts +11 -0
  81. package/dist/core/fallback/retryPolicy.js +14 -0
  82. package/dist/core/health/health.d.ts +3 -0
  83. package/dist/core/health/health.js +5 -0
  84. package/dist/core/health/monitor.d.ts +23 -0
  85. package/dist/core/health/monitor.js +82 -0
  86. package/dist/core/policies/budget.d.ts +19 -0
  87. package/dist/core/policies/budget.js +37 -0
  88. package/dist/core/registry/builtinTasks.d.ts +8 -0
  89. package/dist/core/registry/builtinTasks.js +54 -0
  90. package/dist/core/registry/registry.d.ts +18 -0
  91. package/dist/core/registry/registry.js +33 -0
  92. package/dist/core/registry/taskRegistry.d.ts +15 -0
  93. package/dist/core/registry/taskRegistry.js +30 -0
  94. package/dist/core/router/confidence.d.ts +7 -0
  95. package/dist/core/router/confidence.js +20 -0
  96. package/dist/core/router/dimensions.d.ts +16 -0
  97. package/dist/core/router/dimensions.js +60 -0
  98. package/dist/core/router/executor.d.ts +16 -0
  99. package/dist/core/router/executor.js +25 -0
  100. package/dist/core/router/filter.d.ts +34 -0
  101. package/dist/core/router/filter.js +113 -0
  102. package/dist/core/router/normalize.d.ts +30 -0
  103. package/dist/core/router/normalize.js +119 -0
  104. package/dist/core/router/request.d.ts +4 -0
  105. package/dist/core/router/request.js +21 -0
  106. package/dist/core/router/router.d.ts +32 -0
  107. package/dist/core/router/router.js +195 -0
  108. package/dist/core/router/routingPrefs.d.ts +11 -0
  109. package/dist/core/router/routingPrefs.js +30 -0
  110. package/dist/core/router/scorer.d.ts +19 -0
  111. package/dist/core/router/scorer.js +50 -0
  112. package/dist/core/router/weights.d.ts +9 -0
  113. package/dist/core/router/weights.js +31 -0
  114. package/dist/core/validation/validator.d.ts +16 -0
  115. package/dist/core/validation/validator.js +33 -0
  116. package/dist/discovery/modelCatalog.d.ts +28 -0
  117. package/dist/discovery/modelCatalog.js +105 -0
  118. package/dist/discovery/openapi.d.ts +25 -0
  119. package/dist/discovery/openapi.js +76 -0
  120. package/dist/executions/checkpoint.d.ts +26 -0
  121. package/dist/executions/checkpoint.js +114 -0
  122. package/dist/executions/execution.d.ts +51 -0
  123. package/dist/executions/execution.js +8 -0
  124. package/dist/executions/store.d.ts +52 -0
  125. package/dist/executions/store.js +124 -0
  126. package/dist/generation/generateAdapter.d.ts +17 -0
  127. package/dist/generation/generateAdapter.js +30 -0
  128. package/dist/index.d.ts +147 -0
  129. package/dist/index.js +107 -0
  130. package/dist/learning/feedback.d.ts +9 -0
  131. package/dist/learning/feedback.js +18 -0
  132. package/dist/learning/learningStore.d.ts +68 -0
  133. package/dist/learning/learningStore.js +138 -0
  134. package/dist/learning/performanceStore.d.ts +27 -0
  135. package/dist/learning/performanceStore.js +0 -0
  136. package/dist/marketplace/presets.d.ts +24 -0
  137. package/dist/marketplace/presets.js +52 -0
  138. package/dist/mcp/mcp.d.ts +31 -0
  139. package/dist/mcp/mcp.js +54 -0
  140. package/dist/memory/bm25.d.ts +16 -0
  141. package/dist/memory/bm25.js +56 -0
  142. package/dist/memory/classifier.d.ts +14 -0
  143. package/dist/memory/classifier.js +17 -0
  144. package/dist/memory/memory.d.ts +80 -0
  145. package/dist/memory/memory.js +191 -0
  146. package/dist/orchestration/executor.d.ts +35 -0
  147. package/dist/orchestration/executor.js +65 -0
  148. package/dist/orchestration/orchestrator.d.ts +42 -0
  149. package/dist/orchestration/orchestrator.js +63 -0
  150. package/dist/orchestration/plan.d.ts +37 -0
  151. package/dist/orchestration/plan.js +70 -0
  152. package/dist/orchestration/planner.d.ts +29 -0
  153. package/dist/orchestration/planner.js +69 -0
  154. package/dist/plugin/ai.d.ts +82 -0
  155. package/dist/plugin/ai.js +167 -0
  156. package/dist/probing/probe.d.ts +25 -0
  157. package/dist/probing/probe.js +63 -0
  158. package/dist/providers/factory.d.ts +18 -0
  159. package/dist/providers/factory.js +54 -0
  160. package/dist/providers/httpClient.d.ts +34 -0
  161. package/dist/providers/httpClient.js +80 -0
  162. package/dist/providers/httpProvider.d.ts +49 -0
  163. package/dist/providers/httpProvider.js +135 -0
  164. package/dist/providers/mock/demo.d.ts +13 -0
  165. package/dist/providers/mock/demo.js +58 -0
  166. package/dist/providers/mock/mockProvider.d.ts +35 -0
  167. package/dist/providers/mock/mockProvider.js +121 -0
  168. package/dist/providers/mock/scenarios.d.ts +44 -0
  169. package/dist/providers/mock/scenarios.js +30 -0
  170. package/dist/providers/provider.d.ts +26 -0
  171. package/dist/providers/provider.js +11 -0
  172. package/dist/providers/wire/anthropicWire.d.ts +6 -0
  173. package/dist/providers/wire/anthropicWire.js +83 -0
  174. package/dist/providers/wire/openaiWire.d.ts +7 -0
  175. package/dist/providers/wire/openaiWire.js +81 -0
  176. package/dist/providers/wire/registry.d.ts +8 -0
  177. package/dist/providers/wire/registry.js +20 -0
  178. package/dist/providers/wire/types.d.ts +39 -0
  179. package/dist/providers/wire/types.js +24 -0
  180. package/dist/runtime/config.d.ts +31 -0
  181. package/dist/runtime/config.js +121 -0
  182. package/dist/runtime/context.d.ts +34 -0
  183. package/dist/runtime/context.js +11 -0
  184. package/dist/runtime/events.d.ts +99 -0
  185. package/dist/runtime/events.js +82 -0
  186. package/dist/runtime/host.d.ts +27 -0
  187. package/dist/runtime/host.js +7 -0
  188. package/dist/runtime/intent/classifier.d.ts +30 -0
  189. package/dist/runtime/intent/classifier.js +60 -0
  190. package/dist/runtime/intent/signals.d.ts +19 -0
  191. package/dist/runtime/intent/signals.js +46 -0
  192. package/dist/runtime/modes/availability.d.ts +11 -0
  193. package/dist/runtime/modes/availability.js +17 -0
  194. package/dist/runtime/modes/chat.d.ts +18 -0
  195. package/dist/runtime/modes/chat.js +67 -0
  196. package/dist/runtime/modes/modeResolver.d.ts +43 -0
  197. package/dist/runtime/modes/modeResolver.js +78 -0
  198. package/dist/runtime/policy.d.ts +72 -0
  199. package/dist/runtime/policy.js +59 -0
  200. package/dist/runtime/providerView.d.ts +62 -0
  201. package/dist/runtime/providerView.js +105 -0
  202. package/dist/runtime/routing.d.ts +26 -0
  203. package/dist/runtime/routing.js +65 -0
  204. package/dist/runtime/runtime.d.ts +191 -0
  205. package/dist/runtime/runtime.js +718 -0
  206. package/dist/runtime/types.d.ts +153 -0
  207. package/dist/runtime/types.js +9 -0
  208. package/dist/runtime/workspace/detectors.d.ts +15 -0
  209. package/dist/runtime/workspace/detectors.js +57 -0
  210. package/dist/runtime/workspace/workspace.d.ts +29 -0
  211. package/dist/runtime/workspace/workspace.js +116 -0
  212. package/dist/security/credentials.d.ts +26 -0
  213. package/dist/security/credentials.js +34 -0
  214. package/dist/security/redact.d.ts +16 -0
  215. package/dist/security/redact.js +57 -0
  216. package/dist/skills/builtins/fileAnalyzer.d.ts +7 -0
  217. package/dist/skills/builtins/fileAnalyzer.js +47 -0
  218. package/dist/skills/builtins/repositoryAnalyzer.d.ts +6 -0
  219. package/dist/skills/builtins/repositoryAnalyzer.js +47 -0
  220. package/dist/skills/discovery.d.ts +61 -0
  221. package/dist/skills/discovery.js +211 -0
  222. package/dist/skills/manifest.d.ts +30 -0
  223. package/dist/skills/manifest.js +75 -0
  224. package/dist/skills/registry.d.ts +15 -0
  225. package/dist/skills/registry.js +22 -0
  226. package/dist/skills/skill.d.ts +64 -0
  227. package/dist/skills/skill.js +8 -0
  228. package/dist/store/area.d.ts +54 -0
  229. package/dist/store/area.js +164 -0
  230. package/dist/store/paths.d.ts +15 -0
  231. package/dist/store/paths.js +48 -0
  232. package/dist/store/store.d.ts +59 -0
  233. package/dist/store/store.js +140 -0
  234. package/dist/telemetry/sinks/file.d.ts +12 -0
  235. package/dist/telemetry/sinks/file.js +28 -0
  236. package/dist/telemetry/telemetry.d.ts +36 -0
  237. package/dist/telemetry/telemetry.js +63 -0
  238. package/dist/tools/builtins/filesystem.d.ts +7 -0
  239. package/dist/tools/builtins/filesystem.js +53 -0
  240. package/dist/tools/builtins/git.d.ts +10 -0
  241. package/dist/tools/builtins/git.js +66 -0
  242. package/dist/tools/builtins/shell.d.ts +17 -0
  243. package/dist/tools/builtins/shell.js +91 -0
  244. package/dist/tools/jail.d.ts +12 -0
  245. package/dist/tools/jail.js +98 -0
  246. package/dist/tools/permissions.d.ts +25 -0
  247. package/dist/tools/permissions.js +24 -0
  248. package/dist/tools/registry.d.ts +10 -0
  249. package/dist/tools/registry.js +20 -0
  250. package/dist/tools/runner.d.ts +23 -0
  251. package/dist/tools/runner.js +64 -0
  252. package/dist/tools/tool.d.ts +53 -0
  253. package/dist/tools/tool.js +24 -0
  254. package/dist/tools/untrusted.d.ts +13 -0
  255. package/dist/tools/untrusted.js +30 -0
  256. package/dist/types.d.ts +460 -0
  257. package/dist/types.js +12 -0
  258. package/dist/util/clock.d.ts +6 -0
  259. package/dist/util/clock.js +4 -0
  260. package/dist/util/extractJson.d.ts +8 -0
  261. package/dist/util/extractJson.js +54 -0
  262. package/dist/verification/verify.d.ts +26 -0
  263. package/dist/verification/verify.js +67 -0
  264. package/docs/GUIDE.md +358 -0
  265. package/docs/README.md +21 -0
  266. package/docs/architecture.md +78 -0
  267. package/docs/router.md +376 -0
  268. package/docs/security.md +55 -0
  269. package/package.json +67 -0
@@ -0,0 +1,37 @@
1
+ /**
2
+ * ExecutionPlan + PlanStep — a structured, versioned plan the orchestrator executes. A step names a
3
+ * REGISTERED skill or tool; a plan referencing anything unregistered is invalid (never executed). Plans
4
+ * are data: the model proposes them, the Runtime owns execution and permission enforcement.
5
+ */
6
+ export type PlanStepStatus = 'pending' | 'running' | 'succeeded' | 'failed' | 'skipped';
7
+ export interface PlanStep {
8
+ id: string;
9
+ description: string;
10
+ /** A registered skill id (skill and tool are mutually exclusive per step). */
11
+ skill?: string;
12
+ /** A registered tool id. */
13
+ tool?: string;
14
+ input?: unknown;
15
+ /** Ids of steps that must succeed first. */
16
+ dependsOn?: string[];
17
+ status: PlanStepStatus;
18
+ }
19
+ export interface ExecutionPlan {
20
+ id: string;
21
+ goal: string;
22
+ version: number;
23
+ steps: PlanStep[];
24
+ /** Why this version was (re)created — set on replans. */
25
+ reason?: string;
26
+ }
27
+ export interface PlanValidation {
28
+ ok: boolean;
29
+ errors: string[];
30
+ }
31
+ /** Validate that every step references a registered skill/tool and dependencies/DAG are sound. */
32
+ export declare function validatePlan(plan: ExecutionPlan, available: {
33
+ skills: string[];
34
+ tools: string[];
35
+ }): PlanValidation;
36
+ /** A topological execution order → array of "waves" (each wave's steps can run in parallel). */
37
+ export declare function executionWaves(steps: PlanStep[]): PlanStep[][];
@@ -0,0 +1,70 @@
1
+ /**
2
+ * ExecutionPlan + PlanStep — a structured, versioned plan the orchestrator executes. A step names a
3
+ * REGISTERED skill or tool; a plan referencing anything unregistered is invalid (never executed). Plans
4
+ * are data: the model proposes them, the Runtime owns execution and permission enforcement.
5
+ */
6
+ /** Validate that every step references a registered skill/tool and dependencies/DAG are sound. */
7
+ export function validatePlan(plan, available) {
8
+ const errors = [];
9
+ const skills = new Set(available.skills);
10
+ const tools = new Set(available.tools);
11
+ const ids = new Set(plan.steps.map((s) => s.id));
12
+ if (plan.steps.length === 0)
13
+ errors.push('plan has no steps');
14
+ if (ids.size !== plan.steps.length)
15
+ errors.push('plan has duplicate step ids'); // dupes would silently drop a step
16
+ for (const step of plan.steps) {
17
+ if (!step.skill && !step.tool)
18
+ errors.push(`step ${step.id}: names neither a skill nor a tool`);
19
+ if (step.skill && step.tool)
20
+ errors.push(`step ${step.id}: names both a skill and a tool`);
21
+ if (step.skill && !skills.has(step.skill))
22
+ errors.push(`step ${step.id}: unknown skill '${step.skill}'`);
23
+ if (step.tool && !tools.has(step.tool))
24
+ errors.push(`step ${step.id}: unknown tool '${step.tool}'`);
25
+ for (const dep of step.dependsOn ?? []) {
26
+ if (!ids.has(dep))
27
+ errors.push(`step ${step.id}: depends on unknown step '${dep}'`);
28
+ if (dep === step.id)
29
+ errors.push(`step ${step.id}: depends on itself`);
30
+ }
31
+ }
32
+ if (hasCycle(plan.steps))
33
+ errors.push('plan has a dependency cycle');
34
+ return { ok: errors.length === 0, errors };
35
+ }
36
+ function hasCycle(steps) {
37
+ const deps = new Map(steps.map((s) => [s.id, s.dependsOn ?? []]));
38
+ const state = new Map(); // 0=unseen,1=in-stack,2=done
39
+ const visit = (id) => {
40
+ if (state.get(id) === 1)
41
+ return true;
42
+ if (state.get(id) === 2)
43
+ return false;
44
+ state.set(id, 1);
45
+ for (const d of deps.get(id) ?? [])
46
+ if (deps.has(d) && visit(d))
47
+ return true;
48
+ state.set(id, 2);
49
+ return false;
50
+ };
51
+ return steps.some((s) => visit(s.id));
52
+ }
53
+ /** A topological execution order → array of "waves" (each wave's steps can run in parallel). */
54
+ export function executionWaves(steps) {
55
+ const byId = new Map(steps.map((s) => [s.id, s]));
56
+ const remaining = new Set(steps.map((s) => s.id));
57
+ const done = new Set();
58
+ const waves = [];
59
+ while (remaining.size) {
60
+ const ready = [...remaining].filter((id) => (byId.get(id).dependsOn ?? []).every((d) => done.has(d) || !byId.has(d)));
61
+ if (ready.length === 0)
62
+ break; // cycle or dangling dep (validatePlan catches these)
63
+ waves.push(ready.map((id) => byId.get(id)));
64
+ for (const id of ready) {
65
+ remaining.delete(id);
66
+ done.add(id);
67
+ }
68
+ }
69
+ return waves;
70
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Planner — asks a model (via AI.run structured output) for a plan, then validates it references ONLY
3
+ * registered skills/tools. An unparseable or invalid plan is a planning failure, never something we
4
+ * execute. When nothing maps to the goal, the planner surfaces a clarification rather than guessing.
5
+ */
6
+ import type { AI } from '../plugin/ai.js';
7
+ import type { RoutingPreferences } from '../types.js';
8
+ import type { Skill } from '../skills/skill.js';
9
+ import type { ExecutionPlan } from './plan.js';
10
+ export interface PlannerInput {
11
+ goal: string;
12
+ ai: AI;
13
+ skills: Skill[];
14
+ tools: string[];
15
+ version?: number;
16
+ reason?: string;
17
+ /** Observations from a prior attempt, to inform a replan. */
18
+ priorObservations?: string[];
19
+ /** User exclude/prefer routing applied to the planning model call. */
20
+ routing?: RoutingPreferences;
21
+ }
22
+ export interface PlannerResult {
23
+ plan?: ExecutionPlan;
24
+ /** Set when the planner needs the user to disambiguate or enable a capability. */
25
+ clarification?: string;
26
+ error?: string;
27
+ }
28
+ /** Generate and validate a plan for a goal. */
29
+ export declare function generatePlan(input: PlannerInput): Promise<PlannerResult>;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Planner — asks a model (via AI.run structured output) for a plan, then validates it references ONLY
3
+ * registered skills/tools. An unparseable or invalid plan is a planning failure, never something we
4
+ * execute. When nothing maps to the goal, the planner surfaces a clarification rather than guessing.
5
+ */
6
+ import { validatePlan } from './plan.js';
7
+ function catalog(skills, tools) {
8
+ const skillLines = skills.map((s) => ` - skill "${s.id}": ${s.description}`).join('\n') || ' (none)';
9
+ const toolLines = tools.map((t) => ` - tool "${t}"`).join('\n') || ' (none)';
10
+ return `Available skills:\n${skillLines}\nAvailable tools:\n${toolLines}`;
11
+ }
12
+ /** Generate and validate a plan for a goal. */
13
+ export async function generatePlan(input) {
14
+ if (input.skills.length === 0 && input.tools.length === 0) {
15
+ return { clarification: 'No skills or tools are available to act on this. Register a skill/tool or enable a skill pack.' };
16
+ }
17
+ const prompt = [
18
+ `Goal: ${input.goal}`,
19
+ input.priorObservations?.length ? `Prior attempt observations:\n${input.priorObservations.map((o) => ` - ${o}`).join('\n')}` : '',
20
+ catalog(input.skills, input.tools),
21
+ 'Produce a minimal JSON plan: {"steps":[{"id","description","skill" OR "tool","input","dependsOn":[ids]}]}.',
22
+ 'Use ONLY the skills/tools listed above. If nothing fits, return {"steps":[],"clarification":"<question>"}.',
23
+ ]
24
+ .filter(Boolean)
25
+ .join('\n\n');
26
+ const run = await input.ai.run({
27
+ task: 'plan',
28
+ input: prompt,
29
+ output: { format: 'json' },
30
+ requirements: { intelligence: ['planning', 'reasoning'], output: ['json'] },
31
+ ...(input.routing ? { routing: input.routing } : {}),
32
+ });
33
+ if (!run.ok)
34
+ return { error: `planner run failed: ${run.error?.category ?? 'unknown'}` };
35
+ const json = run.response?.json;
36
+ if (!json || !Array.isArray(json.steps))
37
+ return { error: 'planner did not return a valid plan object' };
38
+ // A clarification always wins — never build a guessed plan when the model asked a question.
39
+ if (typeof json.clarification === 'string' && json.clarification.trim())
40
+ return { clarification: json.clarification };
41
+ // Every step must be a non-null object; anything else is a malformed plan (fail cleanly, never crash).
42
+ if (json.steps.some((s) => s === null || typeof s !== 'object' || Array.isArray(s)))
43
+ return { error: 'planner returned a malformed step' };
44
+ const rawSteps = json.steps;
45
+ const steps = rawSteps.map((s, i) => ({
46
+ id: s.id && typeof s.id === 'string' ? s.id : `auto${i + 1}`,
47
+ description: s.description ?? '',
48
+ ...(s.skill ? { skill: s.skill } : {}),
49
+ ...(s.tool ? { tool: s.tool } : {}),
50
+ ...(s.input !== undefined ? { input: s.input } : {}),
51
+ ...(Array.isArray(s.dependsOn) ? { dependsOn: s.dependsOn } : {}),
52
+ status: 'pending',
53
+ }));
54
+ const plan = {
55
+ id: `plan_${input.version ?? 1}`,
56
+ goal: input.goal,
57
+ version: input.version ?? 1,
58
+ steps,
59
+ ...(input.reason ? { reason: input.reason } : {}),
60
+ };
61
+ const validation = validatePlan(plan, { skills: input.skills.map((s) => s.id), tools: input.tools });
62
+ if (!validation.ok) {
63
+ // Empty plan with no steps → treat as "nothing to do / needs clarification" rather than a hard error.
64
+ if (steps.length === 0)
65
+ return { clarification: 'I could not form a plan for this goal. Can you clarify what you want done?' };
66
+ return { error: `invalid plan: ${validation.errors.join('; ')}` };
67
+ }
68
+ return { plan };
69
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * The AI facade — the ONE public interface. Callers name a task and get a normalized result; they
3
+ * never touch a provider directly. Providers are pluggable: registered programmatically here, or
4
+ * built from config. No method ever returns an API key.
5
+ */
6
+ import { ProviderRegistry } from '../core/registry/registry.js';
7
+ import type { TelemetrySink } from '../telemetry/telemetry.js';
8
+ import { PerformanceStore } from '../learning/performanceStore.js';
9
+ import type { ProbeName, ProbeReport } from '../probing/probe.js';
10
+ import type { AIProvider } from '../providers/provider.js';
11
+ import type { FetchLike } from '../providers/httpClient.js';
12
+ import type { McpToolSource } from '../mcp/mcp.js';
13
+ import type { GenerateOptions } from '../generation/generateAdapter.js';
14
+ import type { OpenApiAnalysis } from '../discovery/openapi.js';
15
+ import type { Clock } from '../util/clock.js';
16
+ import type { HealthStatus, ProviderConfig, ProviderMetadata, RouterConfig, RunRequest, RunResult, TaskDefinition, TelemetryEvent, ToolSpec } from '../types.js';
17
+ export interface AIOptions {
18
+ /** Inject a fetch implementation for offline tests of real adapters. */
19
+ fetchImpl?: FetchLike;
20
+ /** Inject a clock for deterministic timing in tests. */
21
+ clock?: Clock;
22
+ /** Override the environment used to resolve credentials (defaults to process.env). */
23
+ env?: NodeJS.ProcessEnv;
24
+ /** Extra telemetry sinks for centralized observability (e.g. a collector exporter). */
25
+ sinks?: TelemetrySink[];
26
+ }
27
+ /** A key-free view of a registered provider — safe to return from the public API. */
28
+ export interface ProviderInfo {
29
+ id: string;
30
+ name: string;
31
+ kind: AIProvider['kind'];
32
+ privacyClass: AIProvider['privacyClass'];
33
+ enabled: boolean;
34
+ }
35
+ export declare class AI {
36
+ private readonly config;
37
+ private readonly registry;
38
+ private readonly tasks;
39
+ private readonly telemetry;
40
+ private readonly health;
41
+ private readonly performance?;
42
+ private readonly overlay;
43
+ private readonly mcp;
44
+ private readonly buildOpts;
45
+ private readonly router;
46
+ constructor(config?: RouterConfig, options?: AIOptions);
47
+ /** Build an AI from a local config file/path or a remote http(s) URL. */
48
+ static load(pathOrUrl?: string, options?: AIOptions): Promise<AI>;
49
+ /** Register a provider instance (pluggable adapter). Chainable. */
50
+ registerProvider(provider: AIProvider, enabled?: boolean): this;
51
+ /** Register or override a task definition (the QA Brain extension seam). Chainable. */
52
+ registerTask(def: TaskDefinition): this;
53
+ run(request: RunRequest): Promise<RunResult>;
54
+ /** Register an MCP tool source. Its tools are offered to the selected model on `mcp` runs. */
55
+ registerMcpSource(source: McpToolSource): this;
56
+ /** Aggregate tools across registered MCP sources (namespaced by source id). */
57
+ mcpTools(): Promise<ToolSpec[]>;
58
+ /** Add a provider from the marketplace preset catalog. */
59
+ addPreset(presetId: string, overrides?: Partial<ProviderConfig>, enabled?: boolean): this;
60
+ /**
61
+ * Dynamic adapter generation: build and register a provider from an OpenAPI analysis
62
+ * or spec file. Only CONFIG is generated (validated), never code — so it is safe by construction.
63
+ */
64
+ registerFromOpenApi(specPathOrAnalysis: string | OpenApiAnalysis, overrides?: GenerateOptions, enabled?: boolean): AIProvider;
65
+ /** Key-free provider listing. */
66
+ providers(): ProviderInfo[];
67
+ tasksList(): TaskDefinition[];
68
+ telemetryEvents(): TelemetryEvent[];
69
+ /** Run each provider's healthCheck(), seed the monitor, and return the statuses (for `doctor`). */
70
+ checkHealth(): Promise<HealthStatus[]>;
71
+ /** Discover provider identity, models, and capabilities (for `providers`/`models`/`capabilities`). */
72
+ discover(): Promise<ProviderMetadata[]>;
73
+ /** Observed per-(task,provider,model) performance the learning layer has accumulated. */
74
+ performanceSnapshot(): ReturnType<PerformanceStore['snapshot']>;
75
+ /**
76
+ * Opt-in capability probing. Runs minimal probes against a model and applies any VERIFIED
77
+ * results to the routing overlay so later runs trust them. Costs tokens — call deliberately.
78
+ */
79
+ probe(providerId: string, model: string, which?: ProbeName[]): Promise<ProbeReport>;
80
+ /** Internal accessor for tools that operate over the same registry (benchmark, verification). */
81
+ get registryRef(): ProviderRegistry;
82
+ }
@@ -0,0 +1,167 @@
1
+ /**
2
+ * The AI facade — the ONE public interface. Callers name a task and get a normalized result; they
3
+ * never touch a provider directly. Providers are pluggable: registered programmatically here, or
4
+ * built from config. No method ever returns an API key.
5
+ */
6
+ import { Router } from '../core/router/router.js';
7
+ import { ProviderRegistry } from '../core/registry/registry.js';
8
+ import { TaskRegistry } from '../core/registry/taskRegistry.js';
9
+ import { resolveConfig } from '../config/defaults.js';
10
+ import { loadConfigAsync } from '../config/load.js';
11
+ import { MemorySink, MultiSink } from '../telemetry/telemetry.js';
12
+ import { FileSink } from '../telemetry/sinks/file.js';
13
+ import { HealthMonitor } from '../core/health/monitor.js';
14
+ import { PerformanceStore } from '../learning/performanceStore.js';
15
+ import { CapabilityOverlay } from '../core/capabilities/overlay.js';
16
+ import { probeModel, ALL_PROBES } from '../probing/probe.js';
17
+ import { buildProvider } from '../providers/factory.js';
18
+ import { McpRegistry } from '../mcp/mcp.js';
19
+ import { presetToConfig } from '../marketplace/presets.js';
20
+ import { generateProviderConfig, generateProviderConfigFromFile } from '../generation/generateAdapter.js';
21
+ export class AI {
22
+ config;
23
+ registry = new ProviderRegistry();
24
+ tasks;
25
+ telemetry;
26
+ health;
27
+ performance;
28
+ overlay = new CapabilityOverlay();
29
+ mcp = new McpRegistry();
30
+ buildOpts;
31
+ router;
32
+ constructor(config = { providers: [] }, options = {}) {
33
+ this.config = resolveConfig(config);
34
+ this.tasks = new TaskRegistry(this.config.tasks);
35
+ const memory = new MemorySink();
36
+ const sinks = [memory];
37
+ if (this.config.telemetry.enabled && this.config.telemetry.sink === 'file' && this.config.telemetry.path)
38
+ sinks.push(new FileSink(this.config.telemetry.path));
39
+ if (options.sinks)
40
+ sinks.push(...options.sinks);
41
+ this.telemetry = sinks.length > 1 ? new MultiSink(sinks) : memory;
42
+ this.health = new HealthMonitor(this.telemetry, options.clock);
43
+ if (this.config.learning.enabled)
44
+ this.performance = new PerformanceStore();
45
+ this.router = new Router({
46
+ registry: this.registry,
47
+ tasks: this.tasks,
48
+ config: this.config,
49
+ telemetry: this.telemetry,
50
+ health: this.health,
51
+ overlay: this.overlay,
52
+ ...(this.performance ? { performance: this.performance } : {}),
53
+ ...(options.clock ? { clock: options.clock } : {}),
54
+ });
55
+ // Build concrete adapters from config (credential resolved from the env-var NAME). Providers of
56
+ // kind 'mock' are registered programmatically instead.
57
+ this.buildOpts = {
58
+ ...(options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}),
59
+ ...(options.clock ? { clock: options.clock } : {}),
60
+ ...(options.env ? { env: options.env } : {}),
61
+ };
62
+ for (const providerCfg of this.config.providers) {
63
+ if (providerCfg.kind === 'mock')
64
+ continue;
65
+ const provider = buildProvider(providerCfg, this.buildOpts);
66
+ this.registry.register(provider, providerCfg.enabled ?? true);
67
+ }
68
+ }
69
+ /** Build an AI from a local config file/path or a remote http(s) URL. */
70
+ static async load(pathOrUrl, options = {}) {
71
+ return new AI(await loadConfigAsync(pathOrUrl), options);
72
+ }
73
+ /** Register a provider instance (pluggable adapter). Chainable. */
74
+ registerProvider(provider, enabled = true) {
75
+ this.registry.register(provider, enabled);
76
+ return this;
77
+ }
78
+ /** Register or override a task definition (the QA Brain extension seam). Chainable. */
79
+ registerTask(def) {
80
+ this.tasks.register(def);
81
+ return this;
82
+ }
83
+ async run(request) {
84
+ // Attach MCP tools when requested and sources exist (MCP = tool/context layer, not a provider).
85
+ if (request.mcp && this.mcp.list().length > 0) {
86
+ const tools = [...(request.tools ?? []), ...(await this.mcp.allTools())];
87
+ return this.router.run({ ...request, tools });
88
+ }
89
+ return this.router.run(request);
90
+ }
91
+ /** Register an MCP tool source. Its tools are offered to the selected model on `mcp` runs. */
92
+ registerMcpSource(source) {
93
+ this.mcp.register(source);
94
+ return this;
95
+ }
96
+ /** Aggregate tools across registered MCP sources (namespaced by source id). */
97
+ mcpTools() {
98
+ return this.mcp.allTools();
99
+ }
100
+ /** Add a provider from the marketplace preset catalog. */
101
+ addPreset(presetId, overrides = {}, enabled = true) {
102
+ const cfg = presetToConfig(presetId, overrides);
103
+ this.registry.register(buildProvider(cfg, this.buildOpts), enabled);
104
+ return this;
105
+ }
106
+ /**
107
+ * Dynamic adapter generation: build and register a provider from an OpenAPI analysis
108
+ * or spec file. Only CONFIG is generated (validated), never code — so it is safe by construction.
109
+ */
110
+ registerFromOpenApi(specPathOrAnalysis, overrides = {}, enabled = true) {
111
+ const cfg = typeof specPathOrAnalysis === 'string' ? generateProviderConfigFromFile(specPathOrAnalysis, overrides) : generateProviderConfig(specPathOrAnalysis, overrides);
112
+ const provider = buildProvider(cfg, this.buildOpts);
113
+ this.registry.register(provider, enabled);
114
+ return provider;
115
+ }
116
+ /** Key-free provider listing. */
117
+ providers() {
118
+ return this.registry.all().map((p) => ({
119
+ id: p.id,
120
+ name: p.name,
121
+ kind: p.kind,
122
+ privacyClass: p.privacyClass,
123
+ enabled: this.registry.isEnabled(p.id),
124
+ }));
125
+ }
126
+ tasksList() {
127
+ return this.tasks.list();
128
+ }
129
+ telemetryEvents() {
130
+ return this.telemetry.events?.() ?? [];
131
+ }
132
+ /** Run each provider's healthCheck(), seed the monitor, and return the statuses (for `doctor`). */
133
+ async checkHealth() {
134
+ const out = [];
135
+ for (const provider of this.registry.all()) {
136
+ const status = await provider.healthCheck();
137
+ this.health.seed(status);
138
+ out.push(status);
139
+ }
140
+ return out;
141
+ }
142
+ /** Discover provider identity, models, and capabilities (for `providers`/`models`/`capabilities`). */
143
+ async discover() {
144
+ return Promise.all(this.registry.all().map((p) => p.discover()));
145
+ }
146
+ /** Observed per-(task,provider,model) performance the learning layer has accumulated. */
147
+ performanceSnapshot() {
148
+ return this.performance?.snapshot() ?? [];
149
+ }
150
+ /**
151
+ * Opt-in capability probing. Runs minimal probes against a model and applies any VERIFIED
152
+ * results to the routing overlay so later runs trust them. Costs tokens — call deliberately.
153
+ */
154
+ async probe(providerId, model, which = ALL_PROBES) {
155
+ const provider = this.registry.get(providerId);
156
+ if (!provider)
157
+ throw new Error(`unknown provider '${providerId}'`);
158
+ const report = await probeModel(provider, model, which);
159
+ if (report.results.some((r) => r.status === 'verified'))
160
+ this.overlay.set(providerId, model, report.profile);
161
+ return report;
162
+ }
163
+ /** Internal accessor for tools that operate over the same registry (benchmark, verification). */
164
+ get registryRef() {
165
+ return this.registry;
166
+ }
167
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Capability probing. Runs minimal, controlled requests against a real model to VERIFY
3
+ * capabilities the catalog only documents. Opt-in (it costs tokens), minimal, and it never sends
4
+ * secrets or proprietary data — only tiny synthetic prompts. A positive probe promotes a capability to
5
+ * `verified`; a failure is inconclusive and changes nothing (never a silent demotion of documented).
6
+ */
7
+ import type { AIProvider } from '../providers/provider.js';
8
+ import type { CapabilityProfile } from '../types.js';
9
+ export type ProbeName = 'text' | 'structured_output' | 'tool_calling';
10
+ export interface ProbeResult {
11
+ probe: ProbeName;
12
+ group: 'input' | 'output' | 'intelligence' | 'agent';
13
+ key: string;
14
+ status: 'verified' | 'inconclusive';
15
+ detail?: string;
16
+ }
17
+ export interface ProbeReport {
18
+ providerId: string;
19
+ model: string;
20
+ results: ProbeResult[];
21
+ /** The verified capabilities as a profile, ready to merge into an overlay. */
22
+ profile: CapabilityProfile;
23
+ }
24
+ export declare const ALL_PROBES: ProbeName[];
25
+ export declare function probeModel(provider: AIProvider, model: string, which?: ProbeName[]): Promise<ProbeReport>;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Capability probing. Runs minimal, controlled requests against a real model to VERIFY
3
+ * capabilities the catalog only documents. Opt-in (it costs tokens), minimal, and it never sends
4
+ * secrets or proprietary data — only tiny synthetic prompts. A positive probe promotes a capability to
5
+ * `verified`; a failure is inconclusive and changes nothing (never a silent demotion of documented).
6
+ */
7
+ import { emptyProfile } from '../core/capabilities/evidence.js';
8
+ const baseRequest = (model, over) => ({
9
+ taskId: 'probe',
10
+ model,
11
+ input: { text: 'ping' },
12
+ timeoutMs: 20_000,
13
+ sensitivity: 'low',
14
+ params: { maxTokens: 64 },
15
+ ...over,
16
+ });
17
+ export const ALL_PROBES = ['text', 'structured_output', 'tool_calling'];
18
+ export async function probeModel(provider, model, which = ALL_PROBES) {
19
+ const results = [];
20
+ const profile = emptyProfile();
21
+ const verify = (group, key) => {
22
+ const bucket = profile[group];
23
+ bucket[key] = { value: true, evidence: 'verified' };
24
+ };
25
+ for (const probe of which) {
26
+ try {
27
+ if (probe === 'text') {
28
+ const res = await provider.execute(baseRequest(model, { input: { text: 'Reply with the single word: ok' } }));
29
+ const ok = Boolean(res.text && res.text.trim());
30
+ results.push({ probe, group: 'output', key: 'text', status: ok ? 'verified' : 'inconclusive' });
31
+ if (ok) {
32
+ verify('output', 'text');
33
+ verify('input', 'text');
34
+ }
35
+ }
36
+ else if (probe === 'structured_output') {
37
+ const res = await provider.execute(baseRequest(model, { input: { text: 'Return JSON {"probe": true}' }, output: { format: 'json' } }));
38
+ const ok = res.json !== undefined;
39
+ results.push({ probe, group: 'output', key: 'structured_output', status: ok ? 'verified' : 'inconclusive' });
40
+ if (ok) {
41
+ verify('output', 'json');
42
+ verify('output', 'structured_output');
43
+ }
44
+ }
45
+ else if (probe === 'tool_calling') {
46
+ const res = await provider.execute(baseRequest(model, {
47
+ input: { text: 'Call the ping tool.' },
48
+ tools: [{ name: 'ping', description: 'returns pong', parameters: { type: 'object', properties: {} } }],
49
+ }));
50
+ const ok = Boolean(res.toolCalls && res.toolCalls.length > 0 && res.toolCalls.some((c) => c.name === 'ping'));
51
+ results.push({ probe, group: 'agent', key: 'tool_calling', status: ok ? 'verified' : 'inconclusive' });
52
+ if (ok) {
53
+ verify('agent', 'tool_calling');
54
+ verify('agent', 'function_calling');
55
+ }
56
+ }
57
+ }
58
+ catch (e) {
59
+ results.push({ probe, group: 'output', key: probe, status: 'inconclusive', detail: e instanceof Error ? e.name : 'error' });
60
+ }
61
+ }
62
+ return { providerId: provider.id, model, results, profile };
63
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Build a concrete provider from a ProviderConfig. This is the seam that makes providers pluggable by
3
+ * CONFIG: pick vendor defaults, resolve the credential from the env-var NAME, resolve model metadata
4
+ * from the catalog + operator-declared capabilities, and hand it all to the one HttpProvider class.
5
+ * No routing code changes when a provider is added.
6
+ *
7
+ * SECURITY: config may carry only an env-var NAME (`apiKeyEnv`), never a raw key — validated here.
8
+ */
9
+ import type { AIProvider } from './provider.js';
10
+ import type { ProviderConfig } from '../types.js';
11
+ import type { FetchLike } from './httpClient.js';
12
+ import type { Clock } from '../util/clock.js';
13
+ export interface BuildOptions {
14
+ fetchImpl?: FetchLike;
15
+ clock?: Clock;
16
+ env?: NodeJS.ProcessEnv;
17
+ }
18
+ export declare function buildProvider(cfg: ProviderConfig, opts?: BuildOptions): AIProvider;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Build a concrete provider from a ProviderConfig. This is the seam that makes providers pluggable by
3
+ * CONFIG: pick vendor defaults, resolve the credential from the env-var NAME, resolve model metadata
4
+ * from the catalog + operator-declared capabilities, and hand it all to the one HttpProvider class.
5
+ * No routing code changes when a provider is added.
6
+ *
7
+ * SECURITY: config may carry only an env-var NAME (`apiKeyEnv`), never a raw key — validated here.
8
+ */
9
+ import { AIError } from '../core/fallback/errors.js';
10
+ import { Credential } from '../security/credentials.js';
11
+ import { PROVIDER_DEFAULTS } from '../config/providerDefaults.js';
12
+ import { resolveModelMetadata } from '../discovery/modelCatalog.js';
13
+ import { HttpProvider } from './httpProvider.js';
14
+ const KEY_LIKE = /^(sk-|gsk_|Bearer\s|[A-Za-z0-9_-]{40,}$)/;
15
+ export function buildProvider(cfg, opts = {}) {
16
+ if (cfg.kind === 'mock') {
17
+ throw new AIError(`provider '${cfg.id}': kind 'mock' cannot be built from config — register it programmatically`, { category: 'CONFIG' });
18
+ }
19
+ const def = PROVIDER_DEFAULTS[cfg.kind];
20
+ const baseUrl = cfg.baseUrl ?? def.baseUrl;
21
+ if (!baseUrl) {
22
+ throw new AIError(`provider '${cfg.id}' (${cfg.kind}) requires a baseUrl`, { category: 'CONFIG' });
23
+ }
24
+ const apiKeyEnv = cfg.apiKeyEnv ?? def.apiKeyEnv;
25
+ if (apiKeyEnv && KEY_LIKE.test(apiKeyEnv)) {
26
+ throw new AIError(`provider '${cfg.id}': apiKeyEnv must be an env-var NAME, not a key value`, { category: 'CONFIG' });
27
+ }
28
+ const credential = new Credential(apiKeyEnv, opts.env);
29
+ const privacyClass = cfg.privacyClass ?? def.privacyClass;
30
+ const wireShape = cfg.wireShape ?? def.wireShape;
31
+ const modelIds = Array.isArray(cfg.models) && cfg.models.length > 0
32
+ ? cfg.models
33
+ : cfg.defaultModel
34
+ ? [cfg.defaultModel]
35
+ : def.defaultModels;
36
+ const models = modelIds.map((id) => resolveModelMetadata(cfg.id, cfg.kind, id, cfg.capabilities));
37
+ const config = {
38
+ id: cfg.id,
39
+ name: def.name,
40
+ kind: cfg.kind,
41
+ wireShape,
42
+ baseUrl,
43
+ credential,
44
+ privacyClass,
45
+ models,
46
+ requiresKey: def.requiresKey,
47
+ supportsModelListing: def.supportsModelListing,
48
+ ...(cfg.defaultModel ? { defaultModel: cfg.defaultModel } : modelIds[0] ? { defaultModel: modelIds[0] } : {}),
49
+ ...(cfg.headers ? { headers: cfg.headers } : {}),
50
+ ...(opts.fetchImpl ? { fetchImpl: opts.fetchImpl } : {}),
51
+ ...(opts.clock ? { clock: opts.clock } : {}),
52
+ };
53
+ return new HttpProvider(config);
54
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The single HTTP execution path: per-request `AbortSignal.timeout`, same-provider retry on
3
+ * 429/5xx/network with `Retry-After`, and the `response_format` graceful-degrade for gateways that
4
+ * reject it. Two deliberate design choices:
5
+ * - `fetch` is INJECTABLE (so every adapter test runs offline against a mocked fetch);
6
+ * - transport is SPLIT from classification — this layer throws a redacted, categorized AIError; the
7
+ * cross-provider fallback decides what to do next.
8
+ *
9
+ * SECURITY: the request URL is never interpolated into an error (undici embeds it, and it can carry a
10
+ * key-in-query); error bodies are redacted and truncated; the API key lives only in the header the
11
+ * caller built, never in anything this function stores or throws.
12
+ */
13
+ import type { Clock } from '../util/clock.js';
14
+ import type { WireRequest } from './wire/types.js';
15
+ export type FetchLike = typeof fetch;
16
+ export interface CallHttpInput {
17
+ build: (jsonMode: boolean) => WireRequest;
18
+ providerId: string;
19
+ model: string;
20
+ timeoutMs: number;
21
+ maxRetries: number;
22
+ jsonMode: boolean;
23
+ fetchImpl?: FetchLike;
24
+ clock?: Clock;
25
+ onJsonModeDisabled?: () => void;
26
+ }
27
+ export interface CallHttpResult {
28
+ status: number;
29
+ json: unknown;
30
+ durationMs: number;
31
+ attempts: number;
32
+ jsonModeUsed: boolean;
33
+ }
34
+ export declare function callHttp(input: CallHttpInput): Promise<CallHttpResult>;