@danieltmn/tamnora 0.25.0 → 0.26.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 (110) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +13 -25
  3. package/SECURITY.md +3 -4
  4. package/harness/packages/cli/src/cli.js +0 -3
  5. package/harness/packages/cli/src/commands/bridge.js +0 -1
  6. package/harness/packages/cli/src/commands/repl.js +20 -4
  7. package/harness/packages/cli/src/commands/run.js +6 -2
  8. package/harness/packages/cli/src/commands/server.js +1 -1
  9. package/harness/packages/cli/src/commands/tui.js +6 -2
  10. package/harness/packages/cli/src/lib/runtime.js +2 -0
  11. package/harness/packages/cli/src/lib/util.js +2 -2
  12. package/harness/packages/cli/src/tui/app.js +24 -4
  13. package/harness/packages/cli/src/tui/layout.js +1 -1
  14. package/harness/packages/cli/test/tunnel.test.js +5 -32
  15. package/harness/packages/core/src/agent/runAgent.js +5 -2
  16. package/harness/packages/core/src/agents/index.js +113 -0
  17. package/harness/packages/core/src/config/app.js +0 -4
  18. package/harness/packages/core/src/config/home.js +1 -20
  19. package/harness/packages/core/src/config/index.js +6 -8
  20. package/harness/packages/core/src/extensions/load.js +22 -0
  21. package/harness/packages/core/src/frontmatter.js +32 -0
  22. package/harness/packages/core/src/hooks/index.js +2 -16
  23. package/harness/packages/core/src/index.js +12 -14
  24. package/harness/packages/core/src/plugins/index.js +2 -16
  25. package/harness/packages/core/src/procs/project.js +68 -0
  26. package/harness/packages/core/src/procs/static.js +17 -0
  27. package/harness/packages/core/src/providers/index.js +3 -1
  28. package/harness/packages/core/src/providers/ollama.js +4 -1
  29. package/harness/packages/core/src/providers/openaiCompatible.js +6 -1
  30. package/harness/packages/core/src/providers/openrouter.js +5 -1
  31. package/harness/packages/core/src/providers/presets.js +4 -3
  32. package/harness/packages/core/src/providers/reasoning.js +58 -0
  33. package/harness/packages/core/src/rules/index.js +8 -27
  34. package/harness/packages/core/src/skills/index.js +8 -19
  35. package/harness/packages/core/src/storage/sqlite.js +595 -690
  36. package/harness/packages/core/src/tunnel.js +9 -147
  37. package/harness/packages/core/test/agents.test.js +111 -0
  38. package/harness/packages/core/test/home.test.js +2 -35
  39. package/harness/packages/core/test/procs.test.js +3 -64
  40. package/harness/packages/core/test/reasoning.test.js +43 -0
  41. package/harness/packages/core/test/storage.test.js +1 -12
  42. package/harness/packages/server/public/app.js +39 -19
  43. package/harness/packages/server/public/appearance.js +2 -56
  44. package/harness/packages/server/public/boot.js +2 -2
  45. package/harness/packages/server/public/cards.js +2 -21
  46. package/harness/packages/server/public/chat.js +1 -16
  47. package/harness/packages/server/public/chatFormat.js +0 -11
  48. package/harness/packages/server/public/chrome.js +95 -5
  49. package/harness/packages/server/public/commands.js +1 -2
  50. package/harness/packages/server/public/core.js +1 -1
  51. package/harness/packages/server/public/explorer.js +7 -10
  52. package/harness/packages/server/public/icons (1).zip +0 -0
  53. package/harness/packages/server/public/index.html +1228 -1237
  54. package/harness/packages/server/public/landing/boot.js +2 -3
  55. package/harness/packages/server/public/landing/index.html +3 -367
  56. package/harness/packages/server/public/sessions.js +1 -0
  57. package/harness/packages/server/public/settings.js +1255 -1155
  58. package/harness/packages/server/public/settingsNav.js +1 -1
  59. package/harness/packages/server/public/styles.css +2341 -2867
  60. package/harness/packages/server/public/system.js +356 -495
  61. package/harness/packages/server/public/voice.js +6 -22
  62. package/harness/packages/server/src/auth.js +4 -15
  63. package/harness/packages/server/src/cli.js +1 -1
  64. package/harness/packages/server/src/lib/agents.js +60 -0
  65. package/harness/packages/server/src/lib/appearance.js +3 -22
  66. package/harness/packages/server/src/lib/channels/telegram/commands.js +1 -1
  67. package/harness/packages/server/src/lib/channels/telegram/run.js +1 -0
  68. package/harness/packages/server/src/lib/definitions.js +40 -0
  69. package/harness/packages/server/src/lib/prompt.js +11 -3
  70. package/harness/packages/server/src/lib/scheduler.js +4 -0
  71. package/harness/packages/server/src/lib/sessionView.js +1 -0
  72. package/harness/packages/server/src/lib/skills.js +27 -21
  73. package/harness/packages/server/src/lib/tasks.js +71 -23
  74. package/harness/packages/server/src/lib/ttsSettings.js +2 -2
  75. package/harness/packages/server/src/lib/workspace.js +9 -11
  76. package/harness/packages/server/src/routes/agents.js +88 -0
  77. package/harness/packages/server/src/routes/chat.js +9 -44
  78. package/harness/packages/server/src/routes/preview.js +5 -22
  79. package/harness/packages/server/src/routes/procs.js +2 -4
  80. package/harness/packages/server/src/routes/providers.js +7 -0
  81. package/harness/packages/server/src/routes/sessions.js +3 -1
  82. package/harness/packages/server/src/routes/tts.js +1 -1
  83. package/harness/packages/server/src/server.js +8 -5
  84. package/harness/packages/server/test/agents.test.js +194 -0
  85. package/harness/packages/server/test/appearance-route.test.js +3 -3
  86. package/harness/packages/server/test/appearance.test.js +12 -38
  87. package/harness/packages/server/test/chatFormat.test.js +0 -8
  88. package/harness/packages/server/test/consoleTabs.test.js +2 -2
  89. package/harness/packages/server/test/ops.test.js +8 -56
  90. package/harness/packages/server/test/preview.test.js +2 -42
  91. package/harness/packages/server/test/security.test.js +194 -370
  92. package/harness/packages/server/test/settingsNav.test.js +2 -2
  93. package/harness/packages/server/test/tts.test.js +4 -4
  94. package/harness/tamnora.example.json +2 -1
  95. package/package.json +2 -2
  96. package/harness/packages/cli/src/commands/eval.js +0 -186
  97. package/harness/packages/core/src/eval/dataset.js +0 -47
  98. package/harness/packages/core/src/eval/judge.js +0 -39
  99. package/harness/packages/core/src/eval/report.js +0 -48
  100. package/harness/packages/core/src/eval/runTask.js +0 -62
  101. package/harness/packages/core/src/eval/runner.js +0 -153
  102. package/harness/packages/core/src/eval/scorers.js +0 -217
  103. package/harness/packages/core/src/eval/task.js +0 -59
  104. package/harness/packages/core/src/procs/detect.js +0 -149
  105. package/harness/packages/core/test/eval.test.js +0 -144
  106. package/harness/packages/server/src/lib/advisor.js +0 -198
  107. package/harness/packages/server/src/routes/advisor.js +0 -79
  108. package/harness/packages/server/src/routes/eval.js +0 -100
  109. package/harness/packages/server/test/advisor.test.js +0 -249
  110. package/harness/scripts/example-dataset.jsonl +0 -4
@@ -0,0 +1,58 @@
1
+ // Esfuerzo de razonamiento: un vocabulario comun que cada adaptador traduce al
2
+ // parametro de su proveedor. `''` significa "sin override" (default del modelo).
3
+
4
+ export const EFFORT_LEVELS = ['off', 'low', 'medium', 'high', 'max'];
5
+
6
+ export const EFFORT_LABELS = {
7
+ off: 'Sin razonamiento',
8
+ low: 'Bajo',
9
+ medium: 'Medio',
10
+ high: 'Alto',
11
+ max: 'Máximo',
12
+ };
13
+
14
+ const ALIASES = {
15
+ none: 'off',
16
+ minimal: 'low',
17
+ medium: 'medium',
18
+ xhigh: 'max',
19
+ ultra: 'max',
20
+ };
21
+
22
+ /** Normaliza lo que manda el usuario/proveedor al vocabulario comun. */
23
+ export function normalizeEffort(value) {
24
+ if (value === null || value === undefined) return '';
25
+ const raw = String(value).trim().toLowerCase();
26
+ if (!raw || raw === 'auto' || raw === 'default') return '';
27
+ const level = ALIASES[raw] ?? raw;
28
+ return EFFORT_LEVELS.includes(level) ? level : '';
29
+ }
30
+
31
+ /**
32
+ * Agrega al body del request el parametro de esfuerzo que entiende el
33
+ * proveedor. Los adaptadores que no lo soportan (`reasoning: 'none'`) no
34
+ * reciben nada, asi un modelo sin razonamiento no rompe con un 400.
35
+ */
36
+ export function applyReasoningEffort(body, effort, provider = {}) {
37
+ const level = normalizeEffort(effort);
38
+ if (!level) return body;
39
+ const mode = provider?.reasoning ?? 'none';
40
+
41
+ if (mode === 'think') {
42
+ // Ollama: `think` acepta boolean o (en versiones nuevas) un nivel.
43
+ body.think = level === 'off' ? false : level;
44
+ return body;
45
+ }
46
+
47
+ if (mode === 'effort' || mode === 'openai' || mode === 'deepseek') {
48
+ // OpenAI solo llega hasta high; DeepSeek y OpenRouter aceptan max.
49
+ const effortValue = level === 'max' && mode === 'openai' ? 'high' : level === 'off' ? 'none' : level;
50
+ body.reasoning_effort = effortValue;
51
+ if (mode === 'deepseek') {
52
+ body.thinking = { type: level === 'off' ? 'disabled' : 'enabled' };
53
+ }
54
+ return body;
55
+ }
56
+
57
+ return body;
58
+ }
@@ -5,36 +5,17 @@
5
5
  import { readFile } from 'node:fs/promises';
6
6
  import path from 'node:path';
7
7
  import { globToRegExp, globFiles } from '../tools/glob.js';
8
+ import { parseFrontmatter, parseListValue } from '../frontmatter.js';
8
9
 
9
10
  /** Parsea un archivo de reglas: frontmatter (name, paths/globs) + body. */
10
11
  export function parseRuleMarkdown(text, fallbackId = '') {
11
- const source = String(text ?? '');
12
- let name = fallbackId;
13
- let paths = [];
14
- let body = source.trim();
15
- const match = source.match(/^---\s*\r?\n([\s\S]*?)\r?\n---\s*\r?\n?([\s\S]*)$/);
16
- if (match) {
17
- body = match[2].trim();
18
- for (const line of match[1].split(/\r?\n/)) {
19
- const kv = line.match(/^([A-Za-z][\w-]*)\s*:\s*(.*)$/);
20
- if (!kv) continue;
21
- const key = kv[1].toLowerCase();
22
- const value = kv[2].trim();
23
- if (key === 'name') name = value.replace(/^["']|["']$/g, '');
24
- else if (key === 'paths' || key === 'globs' || key === 'path') paths = parseList(value);
25
- }
26
- }
27
- return { name: name || fallbackId, paths: normalizePaths(paths), body };
28
- }
29
-
30
- function parseList(value) {
31
- const raw = String(value ?? '').trim();
32
- if (!raw) return [];
33
- const inner = raw.startsWith('[') && raw.endsWith(']') ? raw.slice(1, -1) : raw;
34
- return inner
35
- .split(',')
36
- .map((s) => s.trim().replace(/^["']|["']$/g, ''))
37
- .filter(Boolean);
12
+ const { fields, body } = parseFrontmatter(text);
13
+ const listed = fields.paths ?? fields.globs ?? fields.path;
14
+ return {
15
+ name: fields.name || fallbackId,
16
+ paths: normalizePaths(listed === undefined ? [] : parseListValue(listed)),
17
+ body,
18
+ };
38
19
  }
39
20
 
40
21
  function normalizePaths(paths) {
@@ -5,28 +5,17 @@
5
5
  import { readdirSync, readFileSync, statSync } from 'node:fs';
6
6
  import { mkdir, writeFile } from 'node:fs/promises';
7
7
  import path from 'node:path';
8
+ import { parseFrontmatter } from '../frontmatter.js';
8
9
 
9
10
  /** Parse a SKILL.md: frontmatter `--- key: value ---` plus body. */
10
11
  export function parseSkillMarkdown(text, fallbackId = '') {
11
- const source = String(text ?? '');
12
- let name = fallbackId;
13
- let description = '';
14
- let when = '';
15
- let body = source.trim();
16
- const match = source.match(/^---\s*\r?\n([\s\S]*?)\r?\n---\s*\r?\n?([\s\S]*)$/);
17
- if (match) {
18
- body = match[2].trim();
19
- for (const line of match[1].split(/\r?\n/)) {
20
- const kv = line.match(/^([A-Za-z][\w-]*)\s*:\s*(.*)$/);
21
- if (!kv) continue;
22
- const key = kv[1].toLowerCase();
23
- const value = kv[2].trim().replace(/^["']|["']$/g, '');
24
- if (key === 'name') name = value;
25
- else if (key === 'description') description = value;
26
- else if (key === 'when' || key === 'when_to_use') when = value;
27
- }
28
- }
29
- return { name: name || fallbackId, description, when, body };
12
+ const { fields, body } = parseFrontmatter(text);
13
+ return {
14
+ name: fields.name || fallbackId,
15
+ description: fields.description || '',
16
+ when: fields.when || fields.when_to_use || '',
17
+ body,
18
+ };
30
19
  }
31
20
 
32
21
  /** List the skills under a root (`<root>/<slug>/SKILL.md`). Missing root -> []. */