@hoilab/ada-cli 0.84.21 → 0.84.22
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.
- package/CHANGELOG.md +20 -0
- package/README.es.md +163 -0
- package/README.md +99 -652
- package/dist/cli/args.d.ts +3 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +11 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/home-screen.d.ts.map +1 -1
- package/dist/cli/home-screen.js +2 -2
- package/dist/cli/home-screen.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +9 -3
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +57 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +449 -73
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +4 -3
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -32
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/engine-personality.d.ts +12 -0
- package/dist/core/engine-personality.d.ts.map +1 -0
- package/dist/core/engine-personality.js +53 -0
- package/dist/core/engine-personality.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +10 -5
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +23 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +2 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/memory-engine/audit-export.d.ts +54 -0
- package/dist/core/memory-engine/audit-export.d.ts.map +1 -0
- package/dist/core/memory-engine/audit-export.js +85 -0
- package/dist/core/memory-engine/audit-export.js.map +1 -0
- package/dist/core/memory-engine/audit.d.ts.map +1 -1
- package/dist/core/memory-engine/audit.js +7 -8
- package/dist/core/memory-engine/audit.js.map +1 -1
- package/dist/core/memory-engine/engine.d.ts +2 -3
- package/dist/core/memory-engine/engine.d.ts.map +1 -1
- package/dist/core/memory-engine/engine.js +148 -50
- package/dist/core/memory-engine/engine.js.map +1 -1
- package/dist/core/memory-engine/inverted-index.d.ts.map +1 -1
- package/dist/core/memory-engine/inverted-index.js +67 -10
- package/dist/core/memory-engine/inverted-index.js.map +1 -1
- package/dist/core/memory-engine/keychain.d.ts.map +1 -1
- package/dist/core/memory-engine/keychain.js +1 -6
- package/dist/core/memory-engine/keychain.js.map +1 -1
- package/dist/core/memory-engine/observation-store.d.ts +1 -0
- package/dist/core/memory-engine/observation-store.d.ts.map +1 -1
- package/dist/core/memory-engine/observation-store.js +37 -8
- package/dist/core/memory-engine/observation-store.js.map +1 -1
- package/dist/core/memory-engine/scanner.d.ts.map +1 -1
- package/dist/core/memory-engine/scanner.js +25 -5
- package/dist/core/memory-engine/scanner.js.map +1 -1
- package/dist/core/memory-engine/security.d.ts.map +1 -1
- package/dist/core/memory-engine/security.js +131 -23
- package/dist/core/memory-engine/security.js.map +1 -1
- package/dist/core/memory-engine/session-indexer.d.ts.map +1 -1
- package/dist/core/memory-engine/session-indexer.js +8 -2
- package/dist/core/memory-engine/session-indexer.js.map +1 -1
- package/dist/core/memory-engine/tools.d.ts +2 -2
- package/dist/core/memory-engine/tools.d.ts.map +1 -1
- package/dist/core/memory-engine/tools.js +14 -7
- package/dist/core/memory-engine/tools.js.map +1 -1
- package/dist/core/memory-engine/vault.d.ts.map +1 -1
- package/dist/core/memory-engine/vault.js +2 -2
- package/dist/core/memory-engine/vault.js.map +1 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +2 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +12 -6
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +11 -6
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/prompt-optimizer.d.ts +53 -0
- package/dist/core/prompt-optimizer.d.ts.map +1 -0
- package/dist/core/prompt-optimizer.js +138 -0
- package/dist/core/prompt-optimizer.js.map +1 -0
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +1 -1
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +2 -1
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts +50 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +233 -7
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +8 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +11 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +52 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +204 -10
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +51 -33
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -5
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +20 -4
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +2 -2
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/project-memory-tool.d.ts.map +1 -1
- package/dist/core/tools/project-memory-tool.js +4 -1
- package/dist/core/tools/project-memory-tool.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/workflows/agent-runner.d.ts +86 -0
- package/dist/core/workflows/agent-runner.d.ts.map +1 -0
- package/dist/core/workflows/agent-runner.js +225 -0
- package/dist/core/workflows/agent-runner.js.map +1 -0
- package/dist/core/workflows/builtins.d.ts +41 -0
- package/dist/core/workflows/builtins.d.ts.map +1 -0
- package/dist/core/workflows/builtins.js +282 -0
- package/dist/core/workflows/builtins.js.map +1 -0
- package/dist/core/workflows/goal-engine/engine.d.ts +134 -0
- package/dist/core/workflows/goal-engine/engine.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/engine.js +462 -0
- package/dist/core/workflows/goal-engine/engine.js.map +1 -0
- package/dist/core/workflows/goal-engine/errors.d.ts +7 -0
- package/dist/core/workflows/goal-engine/errors.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/errors.js +9 -0
- package/dist/core/workflows/goal-engine/errors.js.map +1 -0
- package/dist/core/workflows/goal-engine/index.d.ts +13 -0
- package/dist/core/workflows/goal-engine/index.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/index.js +8 -0
- package/dist/core/workflows/goal-engine/index.js.map +1 -0
- package/dist/core/workflows/goal-engine/persistence.d.ts +31 -0
- package/dist/core/workflows/goal-engine/persistence.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/persistence.js +145 -0
- package/dist/core/workflows/goal-engine/persistence.js.map +1 -0
- package/dist/core/workflows/goal-engine/prompts.d.ts +37 -0
- package/dist/core/workflows/goal-engine/prompts.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/prompts.js +131 -0
- package/dist/core/workflows/goal-engine/prompts.js.map +1 -0
- package/dist/core/workflows/goal-engine/state.d.ts +41 -0
- package/dist/core/workflows/goal-engine/state.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/state.js +397 -0
- package/dist/core/workflows/goal-engine/state.js.map +1 -0
- package/dist/core/workflows/goal-engine/tools.d.ts +31 -0
- package/dist/core/workflows/goal-engine/tools.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/tools.js +211 -0
- package/dist/core/workflows/goal-engine/tools.js.map +1 -0
- package/dist/core/workflows/goal-engine/types.d.ts +286 -0
- package/dist/core/workflows/goal-engine/types.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/types.js +17 -0
- package/dist/core/workflows/goal-engine/types.js.map +1 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.d.ts +23 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.js +72 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.js.map +1 -0
- package/dist/core/workflows/graph-sync.d.ts +67 -0
- package/dist/core/workflows/graph-sync.d.ts.map +1 -0
- package/dist/core/workflows/graph-sync.js +188 -0
- package/dist/core/workflows/graph-sync.js.map +1 -0
- package/dist/core/workflows/graph.d.ts +143 -0
- package/dist/core/workflows/graph.d.ts.map +1 -0
- package/dist/core/workflows/graph.js +319 -0
- package/dist/core/workflows/graph.js.map +1 -0
- package/dist/core/workflows/index.d.ts +18 -0
- package/dist/core/workflows/index.d.ts.map +1 -0
- package/dist/core/workflows/index.js +14 -0
- package/dist/core/workflows/index.js.map +1 -0
- package/dist/core/workflows/journal.d.ts +68 -0
- package/dist/core/workflows/journal.d.ts.map +1 -0
- package/dist/core/workflows/journal.js +83 -0
- package/dist/core/workflows/journal.js.map +1 -0
- package/dist/core/workflows/manager.d.ts +112 -0
- package/dist/core/workflows/manager.d.ts.map +1 -0
- package/dist/core/workflows/manager.js +327 -0
- package/dist/core/workflows/manager.js.map +1 -0
- package/dist/core/workflows/resolve-script.d.ts +35 -0
- package/dist/core/workflows/resolve-script.d.ts.map +1 -0
- package/dist/core/workflows/resolve-script.js +66 -0
- package/dist/core/workflows/resolve-script.js.map +1 -0
- package/dist/core/workflows/runtime.d.ts +49 -0
- package/dist/core/workflows/runtime.d.ts.map +1 -0
- package/dist/core/workflows/runtime.js +301 -0
- package/dist/core/workflows/runtime.js.map +1 -0
- package/dist/core/workflows/shared-store.d.ts +31 -0
- package/dist/core/workflows/shared-store.d.ts.map +1 -0
- package/dist/core/workflows/shared-store.js +80 -0
- package/dist/core/workflows/shared-store.js.map +1 -0
- package/dist/core/workflows/subagent-host.d.ts +50 -0
- package/dist/core/workflows/subagent-host.d.ts.map +1 -0
- package/dist/core/workflows/subagent-host.js +225 -0
- package/dist/core/workflows/subagent-host.js.map +1 -0
- package/dist/core/workflows/tool-workflow.d.ts +22 -0
- package/dist/core/workflows/tool-workflow.d.ts.map +1 -0
- package/dist/core/workflows/tool-workflow.js +120 -0
- package/dist/core/workflows/tool-workflow.js.map +1 -0
- package/dist/core/workflows/types.d.ts +142 -0
- package/dist/core/workflows/types.d.ts.map +1 -0
- package/dist/core/workflows/types.js +26 -0
- package/dist/core/workflows/types.js.map +1 -0
- package/dist/core/workflows/worktree.d.ts +42 -0
- package/dist/core/workflows/worktree.d.ts.map +1 -0
- package/dist/core/workflows/worktree.js +107 -0
- package/dist/core/workflows/worktree.js.map +1 -0
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +6 -2
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +16 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -11
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +4 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +20 -15
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/home-screen.d.ts.map +1 -1
- package/dist/modes/interactive/components/home-screen.js +2 -2
- package/dist/modes/interactive/components/home-screen.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +2 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +16 -6
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/prompt-optimization.d.ts +16 -0
- package/dist/modes/interactive/components/prompt-optimization.d.ts.map +1 -0
- package/dist/modes/interactive/components/prompt-optimization.js +46 -0
- package/dist/modes/interactive/components/prompt-optimization.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +19 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +247 -46
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +8 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +29 -3
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +24 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +677 -34
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +4 -3
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +16 -13
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +20 -6
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +173 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +29 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +1 -1
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/skills/ada-engine/SKILL.md +153 -0
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/docs/compaction.md +15 -0
- package/docs/custom-provider.md +5 -2
- package/docs/extensions.md +11 -2
- package/docs/json.md +7 -2
- package/docs/llama-cpp.md +2 -0
- package/docs/models.md +8 -2
- package/docs/rpc.md +9 -3
- package/docs/settings.md +2 -2
- package/docs/skills.md +4 -3
- package/examples/extensions/border-status-editor.ts +1 -1
- package/examples/extensions/git-checkpoint.ts +2 -2
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/subagent/README.md +1 -1
- package/examples/extensions/subagent/index.ts +6 -1
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +2 -12
- package/package.json +3 -3
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ada Intelligence Engine — tools del Goal Engine.
|
|
3
|
+
*
|
|
4
|
+
* Herramientas que el agente usa durante un goal: goal_complete (con
|
|
5
|
+
* evidencia), goal_blocked, goal_wait, todo (checklist), ask_user_question
|
|
6
|
+
* (cuestionario tipado, pi-ask-user). Se registran en la sesión activa del
|
|
7
|
+
* goal; su estado vive en el GoalEngine (inyectado como "engine").
|
|
8
|
+
*/
|
|
9
|
+
import { Type } from "typebox";
|
|
10
|
+
function ok(_content, extra = {}) {
|
|
11
|
+
return { details: undefined, content: [{ type: "text", text: JSON.stringify({ ok: true, ...extra }) }] };
|
|
12
|
+
}
|
|
13
|
+
function notOk(error) {
|
|
14
|
+
return { details: undefined, content: [{ type: "text", text: JSON.stringify({ ok: false, error }) }] };
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* goal_new — Crea el contrato de un goal (estado setup). Tool de SESIÓN:
|
|
18
|
+
* no depende de un goal activo (a diferencia de goalTools). El agente la usa
|
|
19
|
+
* cuando el usuario pide "crea un goal para X" en lenguaje natural.
|
|
20
|
+
*/
|
|
21
|
+
export function createGoalNewTool(engine, sessionId) {
|
|
22
|
+
return {
|
|
23
|
+
name: "goal_new",
|
|
24
|
+
label: "Crear goal",
|
|
25
|
+
description: "Crea el contrato de un goal del Ada Intelligence Engine en estado setup. El goal NO arranca hasta que el usuario lo aprueba (/goal approve <id> o la tool goal_approve). Usa doneCriteria medibles y verifyCommand ejecutable.",
|
|
26
|
+
promptSnippet: "Crea un goal con contrato (goal_new)",
|
|
27
|
+
promptGuidelines: [
|
|
28
|
+
"Define doneCriteria observables y medibles (nunca vagas).",
|
|
29
|
+
"El goal queda en setup hasta aprobarse — indícalo al usuario.",
|
|
30
|
+
],
|
|
31
|
+
parameters: Type.Object({
|
|
32
|
+
goal: Type.String({ description: "El objetivo verbatim" }),
|
|
33
|
+
doneCriteria: Type.Array(Type.String(), { description: "Criterios medibles de hechura" }),
|
|
34
|
+
verifyCommand: Type.String({ description: "Comando de verificación (o string vacío)" }),
|
|
35
|
+
}),
|
|
36
|
+
async execute(_toolCallId, input) {
|
|
37
|
+
const state = await engine.createGoal({
|
|
38
|
+
goal: input.goal,
|
|
39
|
+
doneCriteria: Array.isArray(input.doneCriteria) ? input.doneCriteria : [],
|
|
40
|
+
verifyCommand: input.verifyCommand ?? "",
|
|
41
|
+
sessionId: sessionId ? sessionId() : undefined,
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
details: undefined,
|
|
45
|
+
content: [
|
|
46
|
+
{
|
|
47
|
+
type: "text",
|
|
48
|
+
text: JSON.stringify({
|
|
49
|
+
ok: true,
|
|
50
|
+
goalId: state.id,
|
|
51
|
+
status: state.status,
|
|
52
|
+
message: `Contrato creado: ${state.id}. Apruebalo con /goal approve ${state.id}`,
|
|
53
|
+
}),
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** Todas las tools del Goal Engine para una sesión con goal activo. */
|
|
61
|
+
export function goalTools(ctx) {
|
|
62
|
+
const { engine, goalId } = ctx;
|
|
63
|
+
return [
|
|
64
|
+
{
|
|
65
|
+
name: "goal_complete",
|
|
66
|
+
label: "Completar goal",
|
|
67
|
+
description: "Declara el goal como completado. EXIGE evidencia citada (archivo:línea o URL) por cada criterio de hechura. Solo funciona si el juez ya emitió veredicto done — sin juez, sin completación.",
|
|
68
|
+
promptSnippet: "Completa el goal con evidencia citada (goal_complete)",
|
|
69
|
+
promptGuidelines: [
|
|
70
|
+
"Nunca completes un goal sin evidencia citada archivo:línea o URL.",
|
|
71
|
+
"Si el juez no ha dado done, sigue trabajando en lugar de forzar la completación.",
|
|
72
|
+
],
|
|
73
|
+
parameters: Type.Object({
|
|
74
|
+
summary: Type.String({ description: "Resumen de lo realizado" }),
|
|
75
|
+
evidence: Type.Array(Type.Object({
|
|
76
|
+
claim: Type.String({ description: "Afirmación verificable" }),
|
|
77
|
+
source: Type.String({ description: "archivo:línea, URL o comando que lo prueba" }),
|
|
78
|
+
}), { description: "Evidencia citada por cada criterio" }),
|
|
79
|
+
}),
|
|
80
|
+
async execute(_toolCallId, input, _signal, _onUpdate, _ctx) {
|
|
81
|
+
const state = await engine.complete(goalId, input.summary, input.evidence.map((e) => ({ ...e, citedBy: "agent" })));
|
|
82
|
+
return state.status === "complete"
|
|
83
|
+
? ok("goal completado", { status: state.status })
|
|
84
|
+
: notOk(state.waiting?.reason ?? "no completado");
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "goal_blocked",
|
|
89
|
+
label: "Bloquear goal",
|
|
90
|
+
description: "Marca el goal como bloqueado con un motivo (necesita intervención del usuario).",
|
|
91
|
+
promptSnippet: "Bloquea el goal con motivo (goal_blocked)",
|
|
92
|
+
parameters: Type.Object({
|
|
93
|
+
reason: Type.String({ description: "Motivo del bloqueo" }),
|
|
94
|
+
}),
|
|
95
|
+
async execute(_toolCallId, input, _signal, _onUpdate, _ctx) {
|
|
96
|
+
const state = await engine.blocked(goalId, input.reason);
|
|
97
|
+
return ok("goal bloqueado", { status: state.status });
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: "goal_wait",
|
|
102
|
+
label: "Esperar",
|
|
103
|
+
description: "Pausa el goal hasta que pase un tiempo o el usuario reanude.",
|
|
104
|
+
promptSnippet: "Pausa el goal (goal_wait)",
|
|
105
|
+
parameters: Type.Object({
|
|
106
|
+
reason: Type.String({ description: "Por qué espera" }),
|
|
107
|
+
resumeAfterMs: Type.Optional(Type.Number({ description: "Reanudar tras N ms" })),
|
|
108
|
+
}),
|
|
109
|
+
async execute(_toolCallId, input, _signal, _onUpdate, _ctx) {
|
|
110
|
+
const state = await engine.pause(goalId, input.reason);
|
|
111
|
+
return ok("goal pausado", { status: state.status, resumeAfterMs: input.resumeAfterMs ?? null });
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: "todo",
|
|
116
|
+
label: "Checklist de tareas",
|
|
117
|
+
description: "Reemplaza o actualiza la checklist de tareas del goal. Cada tarea: id estable (kebab-case), título, estado (pending|active|done). Se muestra en el panel en vivo.",
|
|
118
|
+
promptSnippet: "Actualiza la checklist del goal (todo)",
|
|
119
|
+
parameters: Type.Object({
|
|
120
|
+
tasks: Type.Array(Type.Object({
|
|
121
|
+
id: Type.String({ description: "id estable, kebab-case" }),
|
|
122
|
+
title: Type.String(),
|
|
123
|
+
status: Type.Union([Type.Literal("pending"), Type.Literal("active"), Type.Literal("done")]),
|
|
124
|
+
detail: Type.Optional(Type.String()),
|
|
125
|
+
})),
|
|
126
|
+
}),
|
|
127
|
+
async execute(_toolCallId, input, _signal, _onUpdate, _ctx) {
|
|
128
|
+
const state = await engine.get(goalId);
|
|
129
|
+
if (!state)
|
|
130
|
+
return notOk("goal no encontrado");
|
|
131
|
+
await engine.replaceTasks(goalId, input.tasks);
|
|
132
|
+
return ok("checklist actualizada", { count: input.tasks.length });
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: "ask_user_question",
|
|
137
|
+
label: "Preguntar al usuario",
|
|
138
|
+
description: "Cuando una decisión es ambigua o irreversible, pregunta al usuario con un cuestionario tipado (hasta 4 preguntas; single-select, multi-select o freeform). El goal se bloquea hasta que responda.",
|
|
139
|
+
promptSnippet: "Pregunta al usuario antes de decidir (ask_user_question)",
|
|
140
|
+
promptGuidelines: [
|
|
141
|
+
"Usa ask_user_question cuando vayas a adivinar una decisión ambigua o irreversible.",
|
|
142
|
+
"Máximo 4 preguntas; usa single-select con choices para decisiones cerradas.",
|
|
143
|
+
],
|
|
144
|
+
parameters: Type.Object({
|
|
145
|
+
reason: Type.String({ description: "Contexto de por qué preguntas" }),
|
|
146
|
+
questions: Type.Array(Type.Object({
|
|
147
|
+
question: Type.String(),
|
|
148
|
+
type: Type.Union([
|
|
149
|
+
Type.Literal("single-select"),
|
|
150
|
+
Type.Literal("multi-select"),
|
|
151
|
+
Type.Literal("freeform"),
|
|
152
|
+
]),
|
|
153
|
+
choices: Type.Optional(Type.Array(Type.String())),
|
|
154
|
+
required: Type.Optional(Type.Boolean()),
|
|
155
|
+
}), { maxItems: 4 }),
|
|
156
|
+
}),
|
|
157
|
+
async execute(_toolCallId, input, _signal, _onUpdate, _ctx) {
|
|
158
|
+
const state = await engine.askUser(goalId, input.reason, input.questions.map((q, i) => ({
|
|
159
|
+
id: `q${i + 1}`,
|
|
160
|
+
question: q.question,
|
|
161
|
+
type: q.type,
|
|
162
|
+
choices: q.choices,
|
|
163
|
+
required: q.required,
|
|
164
|
+
})));
|
|
165
|
+
return ok("preguntas enviadas — goal bloqueado hasta respuesta", { status: state.status });
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
];
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* goalSessionTools — variante para una SESIÓN: el goalId se resuelve en cada
|
|
172
|
+
* ejecución al goal activo (o se pasa explícito). Permite registrar las tools
|
|
173
|
+
* del goal sin conocer el id en buildRuntime (los goals se crean después).
|
|
174
|
+
*/
|
|
175
|
+
export async function resolveActiveGoalId(engine) {
|
|
176
|
+
const goals = await engine.list().catch(() => []);
|
|
177
|
+
const active = goals.find((g) => g.status === "active" || g.status === "setup");
|
|
178
|
+
return active?.id ?? null;
|
|
179
|
+
}
|
|
180
|
+
/** Registra las tools del Goal Engine resolviendo el goal activo por llamada. */
|
|
181
|
+
export function goalSessionTools(engine, sessionId) {
|
|
182
|
+
const staticCtx = { engine, goalId: "" };
|
|
183
|
+
// Reusar las tools estáticas: su ctx.goalId se sobreescribe en cada llama
|
|
184
|
+
// re-creando contexto con el goal activo.
|
|
185
|
+
// goal_new no depende de goal activo — se registra tal cual.
|
|
186
|
+
return [
|
|
187
|
+
createGoalNewTool(engine, sessionId),
|
|
188
|
+
...goalTools(staticCtx).map((tool) => wrapResolvingGoal(tool, engine)),
|
|
189
|
+
];
|
|
190
|
+
}
|
|
191
|
+
function wrapResolvingGoal(tool, engine) {
|
|
192
|
+
const execute = tool.execute;
|
|
193
|
+
return {
|
|
194
|
+
...tool,
|
|
195
|
+
execute: async (toolCallId, params, signal, onUpdate, ctx) => {
|
|
196
|
+
const goalId = (await resolveActiveGoalId(engine)) ?? "";
|
|
197
|
+
if (!goalId) {
|
|
198
|
+
return {
|
|
199
|
+
details: undefined,
|
|
200
|
+
content: [{ type: "text", text: JSON.stringify({ ok: false, error: "no hay goal activo" }) }],
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const fresh = goalTools({ engine, goalId }).find((t) => t.name === tool.name);
|
|
204
|
+
if (!fresh || !fresh.execute) {
|
|
205
|
+
return execute(toolCallId, params, signal, onUpdate, ctx);
|
|
206
|
+
}
|
|
207
|
+
return fresh.execute(toolCallId, params, signal, onUpdate, ctx);
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../../src/core/workflows/goal-engine/tools.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Ada Intelligence Engine — tools del Goal Engine.\n *\n * Herramientas que el agente usa durante un goal: goal_complete (con\n * evidencia), goal_blocked, goal_wait, todo (checklist), ask_user_question\n * (cuestionario tipado, pi-ask-user). Se registran en la sesión activa del\n * goal; su estado vive en el GoalEngine (inyectado como \"engine\").\n */\n\nimport { Type } from \"typebox\";\nimport type { AgentToolResult, ExtensionContext, ToolDefinition } from \"../../extensions/types.ts\";\nimport type { GoalEngine } from \"./engine.ts\";\n\nexport interface GoalToolContext {\n\tengine: GoalEngine;\n\tgoalId: string;\n}\n\ntype OkResult = AgentToolResult<undefined>;\n\nfunction ok(_content: string, extra: Record<string, unknown> = {}): OkResult {\n\treturn { details: undefined, content: [{ type: \"text\", text: JSON.stringify({ ok: true, ...extra }) }] };\n}\n\nfunction notOk(error: string): OkResult {\n\treturn { details: undefined, content: [{ type: \"text\", text: JSON.stringify({ ok: false, error }) }] };\n}\n\n/**\n * goal_new — Crea el contrato de un goal (estado setup). Tool de SESIÓN:\n * no depende de un goal activo (a diferencia de goalTools). El agente la usa\n * cuando el usuario pide \"crea un goal para X\" en lenguaje natural.\n */\nexport function createGoalNewTool(engine: GoalEngine, sessionId?: () => string | undefined): ToolDefinition {\n\treturn {\n\t\tname: \"goal_new\",\n\t\tlabel: \"Crear goal\",\n\t\tdescription:\n\t\t\t\"Crea el contrato de un goal del Ada Intelligence Engine en estado setup. El goal NO arranca hasta que el usuario lo aprueba (/goal approve <id> o la tool goal_approve). Usa doneCriteria medibles y verifyCommand ejecutable.\",\n\t\tpromptSnippet: \"Crea un goal con contrato (goal_new)\",\n\t\tpromptGuidelines: [\n\t\t\t\"Define doneCriteria observables y medibles (nunca vagas).\",\n\t\t\t\"El goal queda en setup hasta aprobarse — indícalo al usuario.\",\n\t\t],\n\t\tparameters: Type.Object({\n\t\t\tgoal: Type.String({ description: \"El objetivo verbatim\" }),\n\t\t\tdoneCriteria: Type.Array(Type.String(), { description: \"Criterios medibles de hechura\" }),\n\t\t\tverifyCommand: Type.String({ description: \"Comando de verificación (o string vacío)\" }),\n\t\t}),\n\t\tasync execute(_toolCallId: string, input: { goal: string; doneCriteria: string[]; verifyCommand: string }) {\n\t\t\tconst state = await engine.createGoal({\n\t\t\t\tgoal: input.goal,\n\t\t\t\tdoneCriteria: Array.isArray(input.doneCriteria) ? input.doneCriteria : [],\n\t\t\t\tverifyCommand: input.verifyCommand ?? \"\",\n\t\t\t\tsessionId: sessionId ? sessionId() : undefined,\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tdetails: undefined,\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\tok: true,\n\t\t\t\t\t\t\tgoalId: state.id,\n\t\t\t\t\t\t\tstatus: state.status,\n\t\t\t\t\t\t\tmessage: `Contrato creado: ${state.id}. Apruebalo con /goal approve ${state.id}`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t};\n}\n\n/** Todas las tools del Goal Engine para una sesión con goal activo. */\nexport function goalTools(ctx: GoalToolContext): ToolDefinition[] {\n\tconst { engine, goalId } = ctx;\n\n\treturn [\n\t\t{\n\t\t\tname: \"goal_complete\",\n\t\t\tlabel: \"Completar goal\",\n\t\t\tdescription:\n\t\t\t\t\"Declara el goal como completado. EXIGE evidencia citada (archivo:línea o URL) por cada criterio de hechura. Solo funciona si el juez ya emitió veredicto done — sin juez, sin completación.\",\n\t\t\tpromptSnippet: \"Completa el goal con evidencia citada (goal_complete)\",\n\t\t\tpromptGuidelines: [\n\t\t\t\t\"Nunca completes un goal sin evidencia citada archivo:línea o URL.\",\n\t\t\t\t\"Si el juez no ha dado done, sigue trabajando en lugar de forzar la completación.\",\n\t\t\t],\n\t\t\tparameters: Type.Object({\n\t\t\t\tsummary: Type.String({ description: \"Resumen de lo realizado\" }),\n\t\t\t\tevidence: Type.Array(\n\t\t\t\t\tType.Object({\n\t\t\t\t\t\tclaim: Type.String({ description: \"Afirmación verificable\" }),\n\t\t\t\t\t\tsource: Type.String({ description: \"archivo:línea, URL o comando que lo prueba\" }),\n\t\t\t\t\t}),\n\t\t\t\t\t{ description: \"Evidencia citada por cada criterio\" },\n\t\t\t\t),\n\t\t\t}),\n\t\t\tasync execute(\n\t\t\t\t_toolCallId: string,\n\t\t\t\tinput: { summary: string; evidence: Array<{ claim: string; source: string }> },\n\t\t\t\t_signal: AbortSignal | undefined,\n\t\t\t\t_onUpdate: unknown,\n\t\t\t\t_ctx: ExtensionContext,\n\t\t\t): Promise<OkResult> {\n\t\t\t\tconst state = await engine.complete(\n\t\t\t\t\tgoalId,\n\t\t\t\t\tinput.summary,\n\t\t\t\t\tinput.evidence.map((e) => ({ ...e, citedBy: \"agent\" })),\n\t\t\t\t);\n\t\t\t\treturn state.status === \"complete\"\n\t\t\t\t\t? ok(\"goal completado\", { status: state.status })\n\t\t\t\t\t: notOk(state.waiting?.reason ?? \"no completado\");\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"goal_blocked\",\n\t\t\tlabel: \"Bloquear goal\",\n\t\t\tdescription: \"Marca el goal como bloqueado con un motivo (necesita intervención del usuario).\",\n\t\t\tpromptSnippet: \"Bloquea el goal con motivo (goal_blocked)\",\n\t\t\tparameters: Type.Object({\n\t\t\t\treason: Type.String({ description: \"Motivo del bloqueo\" }),\n\t\t\t}),\n\t\t\tasync execute(\n\t\t\t\t_toolCallId: string,\n\t\t\t\tinput: { reason: string },\n\t\t\t\t_signal: AbortSignal | undefined,\n\t\t\t\t_onUpdate: unknown,\n\t\t\t\t_ctx: ExtensionContext,\n\t\t\t): Promise<OkResult> {\n\t\t\t\tconst state = await engine.blocked(goalId, input.reason);\n\t\t\t\treturn ok(\"goal bloqueado\", { status: state.status });\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"goal_wait\",\n\t\t\tlabel: \"Esperar\",\n\t\t\tdescription: \"Pausa el goal hasta que pase un tiempo o el usuario reanude.\",\n\t\t\tpromptSnippet: \"Pausa el goal (goal_wait)\",\n\t\t\tparameters: Type.Object({\n\t\t\t\treason: Type.String({ description: \"Por qué espera\" }),\n\t\t\t\tresumeAfterMs: Type.Optional(Type.Number({ description: \"Reanudar tras N ms\" })),\n\t\t\t}),\n\t\t\tasync execute(\n\t\t\t\t_toolCallId: string,\n\t\t\t\tinput: { reason: string; resumeAfterMs?: number },\n\t\t\t\t_signal: AbortSignal | undefined,\n\t\t\t\t_onUpdate: unknown,\n\t\t\t\t_ctx: ExtensionContext,\n\t\t\t): Promise<OkResult> {\n\t\t\t\tconst state = await engine.pause(goalId, input.reason);\n\t\t\t\treturn ok(\"goal pausado\", { status: state.status, resumeAfterMs: input.resumeAfterMs ?? null });\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"todo\",\n\t\t\tlabel: \"Checklist de tareas\",\n\t\t\tdescription:\n\t\t\t\t\"Reemplaza o actualiza la checklist de tareas del goal. Cada tarea: id estable (kebab-case), título, estado (pending|active|done). Se muestra en el panel en vivo.\",\n\t\t\tpromptSnippet: \"Actualiza la checklist del goal (todo)\",\n\t\t\tparameters: Type.Object({\n\t\t\t\ttasks: Type.Array(\n\t\t\t\t\tType.Object({\n\t\t\t\t\t\tid: Type.String({ description: \"id estable, kebab-case\" }),\n\t\t\t\t\t\ttitle: Type.String(),\n\t\t\t\t\t\tstatus: Type.Union([Type.Literal(\"pending\"), Type.Literal(\"active\"), Type.Literal(\"done\")]),\n\t\t\t\t\t\tdetail: Type.Optional(Type.String()),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t}),\n\t\t\tasync execute(\n\t\t\t\t_toolCallId: string,\n\t\t\t\tinput: {\n\t\t\t\t\ttasks: Array<{ id: string; title: string; status: \"pending\" | \"active\" | \"done\"; detail?: string }>;\n\t\t\t\t},\n\t\t\t\t_signal: AbortSignal | undefined,\n\t\t\t\t_onUpdate: unknown,\n\t\t\t\t_ctx: ExtensionContext,\n\t\t\t): Promise<OkResult> {\n\t\t\t\tconst state = await engine.get(goalId);\n\t\t\t\tif (!state) return notOk(\"goal no encontrado\");\n\t\t\t\tawait engine.replaceTasks(goalId, input.tasks);\n\t\t\t\treturn ok(\"checklist actualizada\", { count: input.tasks.length });\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"ask_user_question\",\n\t\t\tlabel: \"Preguntar al usuario\",\n\t\t\tdescription:\n\t\t\t\t\"Cuando una decisión es ambigua o irreversible, pregunta al usuario con un cuestionario tipado (hasta 4 preguntas; single-select, multi-select o freeform). El goal se bloquea hasta que responda.\",\n\t\t\tpromptSnippet: \"Pregunta al usuario antes de decidir (ask_user_question)\",\n\t\t\tpromptGuidelines: [\n\t\t\t\t\"Usa ask_user_question cuando vayas a adivinar una decisión ambigua o irreversible.\",\n\t\t\t\t\"Máximo 4 preguntas; usa single-select con choices para decisiones cerradas.\",\n\t\t\t],\n\t\t\tparameters: Type.Object({\n\t\t\t\treason: Type.String({ description: \"Contexto de por qué preguntas\" }),\n\t\t\t\tquestions: Type.Array(\n\t\t\t\t\tType.Object({\n\t\t\t\t\t\tquestion: Type.String(),\n\t\t\t\t\t\ttype: Type.Union([\n\t\t\t\t\t\t\tType.Literal(\"single-select\"),\n\t\t\t\t\t\t\tType.Literal(\"multi-select\"),\n\t\t\t\t\t\t\tType.Literal(\"freeform\"),\n\t\t\t\t\t\t]),\n\t\t\t\t\t\tchoices: Type.Optional(Type.Array(Type.String())),\n\t\t\t\t\t\trequired: Type.Optional(Type.Boolean()),\n\t\t\t\t\t}),\n\t\t\t\t\t{ maxItems: 4 },\n\t\t\t\t),\n\t\t\t}),\n\t\t\tasync execute(\n\t\t\t\t_toolCallId: string,\n\t\t\t\tinput: {\n\t\t\t\t\treason: string;\n\t\t\t\t\tquestions: Array<{\n\t\t\t\t\t\tquestion: string;\n\t\t\t\t\t\ttype: \"single-select\" | \"multi-select\" | \"freeform\";\n\t\t\t\t\t\tchoices?: string[];\n\t\t\t\t\t\trequired?: boolean;\n\t\t\t\t\t}>;\n\t\t\t\t},\n\t\t\t\t_signal: AbortSignal | undefined,\n\t\t\t\t_onUpdate: unknown,\n\t\t\t\t_ctx: ExtensionContext,\n\t\t\t): Promise<OkResult> {\n\t\t\t\tconst state = await engine.askUser(\n\t\t\t\t\tgoalId,\n\t\t\t\t\tinput.reason,\n\t\t\t\t\tinput.questions.map((q, i) => ({\n\t\t\t\t\t\tid: `q${i + 1}`,\n\t\t\t\t\t\tquestion: q.question,\n\t\t\t\t\t\ttype: q.type,\n\t\t\t\t\t\tchoices: q.choices,\n\t\t\t\t\t\trequired: q.required,\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\treturn ok(\"preguntas enviadas — goal bloqueado hasta respuesta\", { status: state.status });\n\t\t\t},\n\t\t},\n\t];\n}\n\n/**\n * goalSessionTools — variante para una SESIÓN: el goalId se resuelve en cada\n * ejecución al goal activo (o se pasa explícito). Permite registrar las tools\n * del goal sin conocer el id en buildRuntime (los goals se crean después).\n */\nexport async function resolveActiveGoalId(engine: GoalEngine): Promise<string | null> {\n\tconst goals = await engine.list().catch(() => []);\n\tconst active = goals.find((g) => g.status === \"active\" || g.status === \"setup\");\n\treturn active?.id ?? null;\n}\n\n/** Registra las tools del Goal Engine resolviendo el goal activo por llamada. */\nexport function goalSessionTools(engine: GoalEngine, sessionId?: () => string | undefined): ToolDefinition[] {\n\tconst staticCtx: GoalToolContext = { engine, goalId: \"\" };\n\t// Reusar las tools estáticas: su ctx.goalId se sobreescribe en cada llama\n\t// re-creando contexto con el goal activo.\n\t// goal_new no depende de goal activo — se registra tal cual.\n\treturn [\n\t\tcreateGoalNewTool(engine, sessionId),\n\t\t...goalTools(staticCtx).map((tool) => wrapResolvingGoal(tool, engine)),\n\t];\n}\n\ntype AnyTool = ToolDefinition<any, any, any>;\n\nfunction wrapResolvingGoal(tool: AnyTool, engine: GoalEngine): AnyTool {\n\tconst execute = tool.execute;\n\treturn {\n\t\t...tool,\n\t\texecute: async (toolCallId, params, signal, onUpdate, ctx) => {\n\t\t\tconst goalId = (await resolveActiveGoalId(engine)) ?? \"\";\n\t\t\tif (!goalId) {\n\t\t\t\treturn {\n\t\t\t\t\tdetails: undefined,\n\t\t\t\t\tcontent: [{ type: \"text\", text: JSON.stringify({ ok: false, error: \"no hay goal activo\" }) }],\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst fresh = goalTools({ engine, goalId }).find((t) => t.name === tool.name);\n\t\t\tif (!fresh || !fresh.execute) {\n\t\t\t\treturn execute(toolCallId, params, signal, onUpdate, ctx);\n\t\t\t}\n\t\t\treturn fresh.execute(toolCallId, params, signal, onUpdate, ctx);\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ada Intelligence Engine — Goal Engine (Fase 4).
|
|
3
|
+
*
|
|
4
|
+
* Tipos del bucle de trabajo autónomo: contrato primero (pi-until-done),
|
|
5
|
+
* fases TDD fijas (pi-task), juez LLM obligatorio, frenos (pi-goal),
|
|
6
|
+
* checklist persistente, ask_user_question (pi-ask-user).
|
|
7
|
+
*/
|
|
8
|
+
export type GoalPhase = "analysis" | "bootstrap" | "red" | "green" | "refactor" | "verify" | "working" | "done";
|
|
9
|
+
export type GoalStatus = "setup" | "planning" | "active" | "paused" | "blocked" | "usage_limited" | "budget_limited" | "complete";
|
|
10
|
+
export type TaskStatus = "pending" | "active" | "running" | "done" | "failed" | "blocked";
|
|
11
|
+
export interface Task {
|
|
12
|
+
id: string;
|
|
13
|
+
title: string;
|
|
14
|
+
status: TaskStatus;
|
|
15
|
+
detail?: string;
|
|
16
|
+
/** runId del workflow dinámico que ejecuta esta sub-tarea (goal-contenedor). */
|
|
17
|
+
workflowRunId?: string;
|
|
18
|
+
/** Resultado resumido del workflow (lo lee el juez). */
|
|
19
|
+
resultSummary?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface EvidenceItem {
|
|
22
|
+
claim: string;
|
|
23
|
+
source: string;
|
|
24
|
+
citedBy: string;
|
|
25
|
+
}
|
|
26
|
+
export type JudgeVerdict = "done" | "continue";
|
|
27
|
+
/** Registro de una iteración completa del goal (historial P3). */
|
|
28
|
+
export interface GoalIterationRecord {
|
|
29
|
+
iteration: number;
|
|
30
|
+
/** Snapshot del plan (sub-tareas) de esa iteración. */
|
|
31
|
+
plan: Task[];
|
|
32
|
+
/** Veredicto del juez al cierre de la iteración (si llegó). */
|
|
33
|
+
verdict?: JudgeVerdict;
|
|
34
|
+
/** Razón del juez / motivo de replan. */
|
|
35
|
+
reason?: string;
|
|
36
|
+
/** Motivo de la re-planificación (si la hubo). */
|
|
37
|
+
replanRationale?: string;
|
|
38
|
+
tokensUsed: number;
|
|
39
|
+
costUsed: number;
|
|
40
|
+
timestamp: string;
|
|
41
|
+
}
|
|
42
|
+
export interface JudgeResult {
|
|
43
|
+
verdict: JudgeVerdict;
|
|
44
|
+
reason: string;
|
|
45
|
+
/** true si el juez se ejecutó con un modelo distinto al que trabaja. */
|
|
46
|
+
crossModel: boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface AskUserQuestion {
|
|
49
|
+
id: string;
|
|
50
|
+
question: string;
|
|
51
|
+
type: "single-select" | "multi-select" | "freeform";
|
|
52
|
+
choices?: string[];
|
|
53
|
+
required?: boolean;
|
|
54
|
+
}
|
|
55
|
+
export interface GoalFrenos {
|
|
56
|
+
/** Número máximo de turnos del bucle (pi-goal: 25 por defecto). */
|
|
57
|
+
maxTurns: number;
|
|
58
|
+
/** Turnos vacíos/idénticos consecutivos que disparan pause (3). */
|
|
59
|
+
repeatTolerance: number;
|
|
60
|
+
/** Ruta del stop-file global (~/.ada-stop). null = desactivado. */
|
|
61
|
+
stopFile: string | null;
|
|
62
|
+
/** Presupuesto de tokens; null = sin límite. */
|
|
63
|
+
tokenBudget: number | null;
|
|
64
|
+
/** Presupuesto de coste $; null = sin límite. */
|
|
65
|
+
costBudget: number | null;
|
|
66
|
+
/** Decisiones irreversibles que requieren confirmación del usuario. */
|
|
67
|
+
askBefore: string[];
|
|
68
|
+
/** Máximo de re-planificaciones completas antes de pausar (P1, default 3). */
|
|
69
|
+
maxReplans?: number;
|
|
70
|
+
}
|
|
71
|
+
export declare const DEFAULT_GOAL_FRENOS: GoalFrenos;
|
|
72
|
+
/** Estado del goal — una instancia se rota (nuevo id) al editar/reanudar. */
|
|
73
|
+
export interface GoalState {
|
|
74
|
+
/** Rotado al editar/reanudar: un turno viejo no puede completar el goal nuevo. */
|
|
75
|
+
id: string;
|
|
76
|
+
/** Sesión que creó el goal (para filtrar por conversación en el panel). */
|
|
77
|
+
sessionId?: string;
|
|
78
|
+
goal: string;
|
|
79
|
+
phase: GoalPhase;
|
|
80
|
+
status: GoalStatus;
|
|
81
|
+
doneCriteria: string[];
|
|
82
|
+
verifyCommand: string;
|
|
83
|
+
tasks: Task[];
|
|
84
|
+
iteration: number;
|
|
85
|
+
iterations: GoalIterationRecord[];
|
|
86
|
+
replanRationale?: string;
|
|
87
|
+
evidence: EvidenceItem[];
|
|
88
|
+
judge: {
|
|
89
|
+
model: "cross" | "same" | null;
|
|
90
|
+
lastVerdict?: JudgeVerdict;
|
|
91
|
+
lastReason?: string;
|
|
92
|
+
};
|
|
93
|
+
turnsUsed: number;
|
|
94
|
+
tokensUsed: number;
|
|
95
|
+
costUsed: number;
|
|
96
|
+
repeatedTurns: number;
|
|
97
|
+
lastAgentSummary: string;
|
|
98
|
+
/**
|
|
99
|
+
* Huella del árbol de trabajo en el último FALLO. Si una sub-tarea vuelve a
|
|
100
|
+
* fallar con la misma huella, el agente no cambió nada: no es un intento, es
|
|
101
|
+
* el mismo intento. Ver `worktree-fingerprint.ts`.
|
|
102
|
+
*/
|
|
103
|
+
lastFailureFingerprint?: string;
|
|
104
|
+
waiting?: {
|
|
105
|
+
reason: string;
|
|
106
|
+
resumeAfterMs?: number;
|
|
107
|
+
};
|
|
108
|
+
pendingQuestions?: AskUserQuestion[];
|
|
109
|
+
createdAt: string;
|
|
110
|
+
updatedAt: string;
|
|
111
|
+
}
|
|
112
|
+
export type GoalAction = {
|
|
113
|
+
type: "goal_create";
|
|
114
|
+
goal: string;
|
|
115
|
+
doneCriteria: string[];
|
|
116
|
+
verifyCommand: string;
|
|
117
|
+
sessionId?: string;
|
|
118
|
+
} | {
|
|
119
|
+
type: "goal_task_add";
|
|
120
|
+
title: string;
|
|
121
|
+
} | {
|
|
122
|
+
type: "goal_approve";
|
|
123
|
+
} | {
|
|
124
|
+
type: "goal_tasks";
|
|
125
|
+
tasks: Task[];
|
|
126
|
+
} | {
|
|
127
|
+
type: "goal_task_update";
|
|
128
|
+
taskId: string;
|
|
129
|
+
status: TaskStatus;
|
|
130
|
+
} | {
|
|
131
|
+
type: "goal_task_launched";
|
|
132
|
+
taskId: string;
|
|
133
|
+
workflowRunId: string;
|
|
134
|
+
} | {
|
|
135
|
+
type: "goal_task_result";
|
|
136
|
+
taskId: string;
|
|
137
|
+
status: TaskStatus;
|
|
138
|
+
summary?: string;
|
|
139
|
+
} | {
|
|
140
|
+
type: "goal_phase";
|
|
141
|
+
phase: GoalPhase;
|
|
142
|
+
} | {
|
|
143
|
+
type: "goal_agent_turn";
|
|
144
|
+
summary: string;
|
|
145
|
+
evidence?: EvidenceItem[];
|
|
146
|
+
tokens?: number;
|
|
147
|
+
cost?: number;
|
|
148
|
+
tasks?: Array<{
|
|
149
|
+
taskId: string;
|
|
150
|
+
status: TaskStatus;
|
|
151
|
+
}>;
|
|
152
|
+
} | {
|
|
153
|
+
type: "goal_pause";
|
|
154
|
+
reason?: string;
|
|
155
|
+
} | {
|
|
156
|
+
type: "goal_resume";
|
|
157
|
+
} | {
|
|
158
|
+
type: "goal_blocked";
|
|
159
|
+
reason: string;
|
|
160
|
+
} | {
|
|
161
|
+
type: "goal_wait";
|
|
162
|
+
reason: string;
|
|
163
|
+
resumeAfterMs?: number;
|
|
164
|
+
} | {
|
|
165
|
+
type: "goal_questions";
|
|
166
|
+
questions: AskUserQuestion[];
|
|
167
|
+
reason: string;
|
|
168
|
+
} | {
|
|
169
|
+
type: "goal_answers";
|
|
170
|
+
answers: Record<string, string[]>;
|
|
171
|
+
} | {
|
|
172
|
+
type: "goal_usage_limited";
|
|
173
|
+
} | {
|
|
174
|
+
type: "goal_budget_limited";
|
|
175
|
+
} | {
|
|
176
|
+
type: "goal_judge";
|
|
177
|
+
verdict: JudgeVerdict;
|
|
178
|
+
reason: string;
|
|
179
|
+
crossModel: boolean;
|
|
180
|
+
} | {
|
|
181
|
+
type: "goal_replan";
|
|
182
|
+
tasks: Array<{
|
|
183
|
+
title: string;
|
|
184
|
+
}>;
|
|
185
|
+
rationale?: string;
|
|
186
|
+
} | {
|
|
187
|
+
type: "goal_task_remove";
|
|
188
|
+
taskId: string;
|
|
189
|
+
} | {
|
|
190
|
+
type: "goal_task_move";
|
|
191
|
+
taskId: string;
|
|
192
|
+
dir: "up" | "down";
|
|
193
|
+
} | {
|
|
194
|
+
type: "goal_complete";
|
|
195
|
+
summary: string;
|
|
196
|
+
evidence: EvidenceItem[];
|
|
197
|
+
};
|
|
198
|
+
export interface GoalEventMap {
|
|
199
|
+
goal_update: {
|
|
200
|
+
goal: GoalState;
|
|
201
|
+
task?: Task;
|
|
202
|
+
};
|
|
203
|
+
goal_phase: {
|
|
204
|
+
goalId: string;
|
|
205
|
+
phase: GoalPhase;
|
|
206
|
+
};
|
|
207
|
+
goal_agent: {
|
|
208
|
+
goalId: string;
|
|
209
|
+
agent: {
|
|
210
|
+
id: string;
|
|
211
|
+
label: string;
|
|
212
|
+
model?: string;
|
|
213
|
+
detail?: string;
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
goal_judge: {
|
|
217
|
+
goalId: string;
|
|
218
|
+
verdict: JudgeVerdict;
|
|
219
|
+
reason: string;
|
|
220
|
+
};
|
|
221
|
+
goal_question: {
|
|
222
|
+
goalId: string;
|
|
223
|
+
questions: AskUserQuestion[];
|
|
224
|
+
};
|
|
225
|
+
goal_finished: {
|
|
226
|
+
goalId: string;
|
|
227
|
+
status: GoalStatus;
|
|
228
|
+
verdict?: JudgeVerdict;
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
export type GoalEventType = keyof GoalEventMap;
|
|
232
|
+
export type GoalEventListener = <K extends GoalEventType>(type: K, payload: GoalEventMap[K]) => void;
|
|
233
|
+
export type GoalJudgeFn = (input: {
|
|
234
|
+
goal: string;
|
|
235
|
+
doneCriteria: string[];
|
|
236
|
+
verifyCommand: string;
|
|
237
|
+
evidence: EvidenceItem[];
|
|
238
|
+
phase: GoalPhase;
|
|
239
|
+
}) => Promise<JudgeResult>;
|
|
240
|
+
export type GoalReplanFn = (input: {
|
|
241
|
+
goal: string;
|
|
242
|
+
doneCriteria: string[];
|
|
243
|
+
verifyCommand: string;
|
|
244
|
+
evidence: EvidenceItem[];
|
|
245
|
+
currentTasks: Task[];
|
|
246
|
+
lastVerdict?: JudgeVerdict;
|
|
247
|
+
lastReason?: string;
|
|
248
|
+
}) => Promise<{
|
|
249
|
+
tasks: Array<{
|
|
250
|
+
title: string;
|
|
251
|
+
}>;
|
|
252
|
+
rationale?: string;
|
|
253
|
+
}>;
|
|
254
|
+
export interface GoalWorkInput {
|
|
255
|
+
goal: string;
|
|
256
|
+
phase: GoalPhase;
|
|
257
|
+
doneCriteria: string[];
|
|
258
|
+
verifyCommand: string;
|
|
259
|
+
tasks: Task[];
|
|
260
|
+
evidence: EvidenceItem[];
|
|
261
|
+
turn: number;
|
|
262
|
+
maxTurns: number;
|
|
263
|
+
}
|
|
264
|
+
export interface GoalWorkResult {
|
|
265
|
+
summary: string;
|
|
266
|
+
evidence?: EvidenceItem[];
|
|
267
|
+
tokens?: number;
|
|
268
|
+
cost?: number;
|
|
269
|
+
tasks?: Array<{
|
|
270
|
+
taskId: string;
|
|
271
|
+
status: TaskStatus;
|
|
272
|
+
}>;
|
|
273
|
+
}
|
|
274
|
+
export type GoalWorkFn = (input: GoalWorkInput) => Promise<GoalWorkResult>;
|
|
275
|
+
export interface GoalPersistence {
|
|
276
|
+
save(state: GoalState): Promise<void>;
|
|
277
|
+
load(id: string): Promise<GoalState | null>;
|
|
278
|
+
list(): Promise<Array<{
|
|
279
|
+
id: string;
|
|
280
|
+
goal: string;
|
|
281
|
+
status: GoalStatus;
|
|
282
|
+
phase: GoalPhase;
|
|
283
|
+
updatedAt: string;
|
|
284
|
+
}>>;
|
|
285
|
+
}
|
|
286
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/workflows/goal-engine/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,KAAK,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAEhH,MAAM,MAAM,UAAU,GACnB,OAAO,GACP,UAAU,GACV,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,eAAe,GACf,gBAAgB,GAChB,UAAU,CAAC;AAEd,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE1F,MAAM,WAAW,IAAI;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,CAAC;AAE/C,mEAAkE;AAClE,MAAM,WAAW,mBAAmB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAuD;IACvD,IAAI,EAAE,IAAI,EAAE,CAAC;IACb,iEAA+D;IAC/D,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,0CAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,yEAAwE;IACxE,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,eAAe,GAAG,cAAc,GAAG,UAAU,CAAC;IACpD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IAC1B,qEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAmE;IACnE,eAAe,EAAE,MAAM,CAAC;IACxB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,iDAAgD;IAChD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kDAAiD;IACjD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wEAAuE;IACvE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,+EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,mBAAmB,EAAE,UAQjC,CAAC;AAEF,+EAA6E;AAC7E,MAAM,WAAW,SAAS;IACzB,kFAAkF;IAClF,EAAE,EAAE,MAAM,CAAC;IACX,8EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IAEnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IAEtB,KAAK,EAAE,IAAI,EAAE,CAAC;IAEd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,EAAE;QACN,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;QAC/B,WAAW,CAAC,EAAE,YAAY,CAAC;QAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IAEF,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB;AAID,MAAM,MAAM,UAAU,GACnB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACxG;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAClF;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GACxC;IACA,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;CACrD,GACD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,SAAS,EAAE,eAAe,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,oBAAoB,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,qBAAqB,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,GAClF;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5E;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC;AAIxE,MAAM,WAAW,YAAY;IAC5B,WAAW,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,IAAI,CAAC,EAAE,IAAI,CAAA;KAAE,CAAC;IAC9C,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC;IACjD,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IACtG,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,aAAa,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,eAAe,EAAE,CAAA;KAAE,CAAC;IAChE,aAAa,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAC;QAAC,OAAO,CAAC,EAAE,YAAY,CAAA;KAAE,CAAC;CAC9E;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,YAAY,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,SAAS,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAIrG,MAAM,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,EAAE,SAAS,CAAC;CACjB,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAI3B,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,YAAY,EAAE,IAAI,EAAE,CAAC;IACrB,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,KAAK,OAAO,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAIvE,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;CACtD;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;AAI3E,MAAM,WAAW,eAAe;IAC/B,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC5C,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAC;QAAC,KAAK,EAAE,SAAS,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;CAC9G","sourcesContent":["/**\n * Ada Intelligence Engine — Goal Engine (Fase 4).\n *\n * Tipos del bucle de trabajo autónomo: contrato primero (pi-until-done),\n * fases TDD fijas (pi-task), juez LLM obligatorio, frenos (pi-goal),\n * checklist persistente, ask_user_question (pi-ask-user).\n */\n\nexport type GoalPhase = \"analysis\" | \"bootstrap\" | \"red\" | \"green\" | \"refactor\" | \"verify\" | \"working\" | \"done\";\n\nexport type GoalStatus =\n\t| \"setup\" // contrato creado, pendiente de approve\n\t| \"planning\" // contrato aprobado, planificando tareas\n\t| \"active\" // bucle corriendo\n\t| \"paused\" // pausado por freno/usuario\n\t| \"blocked\" // bloqueado (esperando input)\n\t| \"usage_limited\" // token budget agotado\n\t| \"budget_limited\" // coste agotado\n\t| \"complete\";\n\nexport type TaskStatus = \"pending\" | \"active\" | \"running\" | \"done\" | \"failed\" | \"blocked\";\n\nexport interface Task {\n\tid: string;\n\ttitle: string;\n\tstatus: TaskStatus;\n\tdetail?: string;\n\t/** runId del workflow dinámico que ejecuta esta sub-tarea (goal-contenedor). */\n\tworkflowRunId?: string;\n\t/** Resultado resumido del workflow (lo lee el juez). */\n\tresultSummary?: string;\n}\n\nexport interface EvidenceItem {\n\tclaim: string;\n\tsource: string; // file:line | url | comando\n\tcitedBy: string; // quién la cita (agente/fase)\n}\n\nexport type JudgeVerdict = \"done\" | \"continue\";\n\n/** Registro de una iteración completa del goal (historial P3). */\nexport interface GoalIterationRecord {\n\titeration: number;\n\t/** Snapshot del plan (sub-tareas) de esa iteración. */\n\tplan: Task[];\n\t/** Veredicto del juez al cierre de la iteración (si llegó). */\n\tverdict?: JudgeVerdict;\n\t/** Razón del juez / motivo de replan. */\n\treason?: string;\n\t/** Motivo de la re-planificación (si la hubo). */\n\treplanRationale?: string;\n\ttokensUsed: number;\n\tcostUsed: number;\n\ttimestamp: string;\n}\n\nexport interface JudgeResult {\n\tverdict: JudgeVerdict;\n\treason: string;\n\t/** true si el juez se ejecutó con un modelo distinto al que trabaja. */\n\tcrossModel: boolean;\n}\n\nexport interface AskUserQuestion {\n\tid: string;\n\tquestion: string;\n\ttype: \"single-select\" | \"multi-select\" | \"freeform\";\n\tchoices?: string[];\n\trequired?: boolean;\n}\n\nexport interface GoalFrenos {\n\t/** Número máximo de turnos del bucle (pi-goal: 25 por defecto). */\n\tmaxTurns: number;\n\t/** Turnos vacíos/idénticos consecutivos que disparan pause (3). */\n\trepeatTolerance: number;\n\t/** Ruta del stop-file global (~/.ada-stop). null = desactivado. */\n\tstopFile: string | null;\n\t/** Presupuesto de tokens; null = sin límite. */\n\ttokenBudget: number | null;\n\t/** Presupuesto de coste $; null = sin límite. */\n\tcostBudget: number | null;\n\t/** Decisiones irreversibles que requieren confirmación del usuario. */\n\taskBefore: string[];\n\t/** Máximo de re-planificaciones completas antes de pausar (P1, default 3). */\n\tmaxReplans?: number;\n}\n\nexport const DEFAULT_GOAL_FRENOS: GoalFrenos = {\n\tmaxTurns: 25,\n\trepeatTolerance: 3,\n\tstopFile: null,\n\ttokenBudget: null,\n\tcostBudget: null,\n\taskBefore: [\"publish\", \"release\", \"delete\", \"rm -rf\", \"drop table\", \"spend\", \"buy\"],\n\tmaxReplans: 3,\n};\n\n/** Estado del goal — una instancia se rota (nuevo id) al editar/reanudar. */\nexport interface GoalState {\n\t/** Rotado al editar/reanudar: un turno viejo no puede completar el goal nuevo. */\n\tid: string;\n\t/** Sesión que creó el goal (para filtrar por conversación en el panel). */\n\tsessionId?: string;\n\tgoal: string; // verbatim\n\tphase: GoalPhase;\n\tstatus: GoalStatus;\n\t// ── contrato (pi-until-done) ──\n\tdoneCriteria: string[];\n\tverifyCommand: string;\n\t// ── plan ──\n\ttasks: Task[];\n\t// ── iteraciones (P3): historial completo de replans/veredictos ──\n\titeration: number; // actual (1-indexed)\n\titerations: GoalIterationRecord[];\n\treplanRationale?: string; // último motivo de re-planificación\n\t// ── evidencia y juez ──\n\tevidence: EvidenceItem[];\n\tjudge: {\n\t\tmodel: \"cross\" | \"same\" | null;\n\t\tlastVerdict?: JudgeVerdict;\n\t\tlastReason?: string;\n\t};\n\t// ── presupuesto y frenos ──\n\tturnsUsed: number;\n\ttokensUsed: number;\n\tcostUsed: number;\n\trepeatedTurns: number;\n\tlastAgentSummary: string; // para el repeat detector\n\t/**\n\t * Huella del árbol de trabajo en el último FALLO. Si una sub-tarea vuelve a\n\t * fallar con la misma huella, el agente no cambió nada: no es un intento, es\n\t * el mismo intento. Ver `worktree-fingerprint.ts`.\n\t */\n\tlastFailureFingerprint?: string;\n\twaiting?: { reason: string; resumeAfterMs?: number };\n\tpendingQuestions?: AskUserQuestion[];\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\n// ─── Acciones del reducer ───\n\nexport type GoalAction =\n\t| { type: \"goal_create\"; goal: string; doneCriteria: string[]; verifyCommand: string; sessionId?: string }\n\t| { type: \"goal_task_add\"; title: string }\n\t| { type: \"goal_approve\" }\n\t| { type: \"goal_tasks\"; tasks: Task[] }\n\t| { type: \"goal_task_update\"; taskId: string; status: TaskStatus }\n\t| { type: \"goal_task_launched\"; taskId: string; workflowRunId: string }\n\t| { type: \"goal_task_result\"; taskId: string; status: TaskStatus; summary?: string }\n\t| { type: \"goal_phase\"; phase: GoalPhase }\n\t| {\n\t\t\ttype: \"goal_agent_turn\";\n\t\t\tsummary: string;\n\t\t\tevidence?: EvidenceItem[];\n\t\t\ttokens?: number;\n\t\t\tcost?: number;\n\t\t\ttasks?: Array<{ taskId: string; status: TaskStatus }>;\n\t }\n\t| { type: \"goal_pause\"; reason?: string }\n\t| { type: \"goal_resume\" }\n\t| { type: \"goal_blocked\"; reason: string }\n\t| { type: \"goal_wait\"; reason: string; resumeAfterMs?: number }\n\t| { type: \"goal_questions\"; questions: AskUserQuestion[]; reason: string }\n\t| { type: \"goal_answers\"; answers: Record<string, string[]> }\n\t| { type: \"goal_usage_limited\" }\n\t| { type: \"goal_budget_limited\" }\n\t| { type: \"goal_judge\"; verdict: JudgeVerdict; reason: string; crossModel: boolean }\n\t| { type: \"goal_replan\"; tasks: Array<{ title: string }>; rationale?: string }\n\t| { type: \"goal_task_remove\"; taskId: string }\n\t| { type: \"goal_task_move\"; taskId: string; dir: \"up\" | \"down\" }\n\t| { type: \"goal_complete\"; summary: string; evidence: EvidenceItem[] };\n\n// ─── Eventos para la UI (Fase 5) ───\n\nexport interface GoalEventMap {\n\tgoal_update: { goal: GoalState; task?: Task };\n\tgoal_phase: { goalId: string; phase: GoalPhase };\n\tgoal_agent: { goalId: string; agent: { id: string; label: string; model?: string; detail?: string } };\n\tgoal_judge: { goalId: string; verdict: JudgeVerdict; reason: string };\n\tgoal_question: { goalId: string; questions: AskUserQuestion[] };\n\tgoal_finished: { goalId: string; status: GoalStatus; verdict?: JudgeVerdict };\n}\n\nexport type GoalEventType = keyof GoalEventMap;\nexport type GoalEventListener = <K extends GoalEventType>(type: K, payload: GoalEventMap[K]) => void;\n\n// ─── Interfaz del juez LLM (inyectable) ───\n\nexport type GoalJudgeFn = (input: {\n\tgoal: string;\n\tdoneCriteria: string[];\n\tverifyCommand: string;\n\tevidence: EvidenceItem[];\n\tphase: GoalPhase;\n}) => Promise<JudgeResult>;\n\n// ─── Interfaz de re-planificación (P1, inyectable) ───\n\nexport type GoalReplanFn = (input: {\n\tgoal: string;\n\tdoneCriteria: string[];\n\tverifyCommand: string;\n\tevidence: EvidenceItem[];\n\tcurrentTasks: Task[];\n\tlastVerdict?: JudgeVerdict;\n\tlastReason?: string;\n}) => Promise<{ tasks: Array<{ title: string }>; rationale?: string }>;\n\n// ─── Interfaz del agente de trabajo (inyectable) ───\n\nexport interface GoalWorkInput {\n\tgoal: string;\n\tphase: GoalPhase;\n\tdoneCriteria: string[];\n\tverifyCommand: string;\n\ttasks: Task[];\n\tevidence: EvidenceItem[];\n\tturn: number;\n\tmaxTurns: number;\n}\n\nexport interface GoalWorkResult {\n\tsummary: string;\n\tevidence?: EvidenceItem[];\n\ttokens?: number;\n\tcost?: number;\n\ttasks?: Array<{ taskId: string; status: TaskStatus }>;\n}\n\nexport type GoalWorkFn = (input: GoalWorkInput) => Promise<GoalWorkResult>;\n\n// ─── Persistencia (inyectable) ───\n\nexport interface GoalPersistence {\n\tsave(state: GoalState): Promise<void>;\n\tload(id: string): Promise<GoalState | null>;\n\tlist(): Promise<Array<{ id: string; goal: string; status: GoalStatus; phase: GoalPhase; updatedAt: string }>>;\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ada Intelligence Engine — Goal Engine (Fase 4).
|
|
3
|
+
*
|
|
4
|
+
* Tipos del bucle de trabajo autónomo: contrato primero (pi-until-done),
|
|
5
|
+
* fases TDD fijas (pi-task), juez LLM obligatorio, frenos (pi-goal),
|
|
6
|
+
* checklist persistente, ask_user_question (pi-ask-user).
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_GOAL_FRENOS = {
|
|
9
|
+
maxTurns: 25,
|
|
10
|
+
repeatTolerance: 3,
|
|
11
|
+
stopFile: null,
|
|
12
|
+
tokenBudget: null,
|
|
13
|
+
costBudget: null,
|
|
14
|
+
askBefore: ["publish", "release", "delete", "rm -rf", "drop table", "spend", "buy"],
|
|
15
|
+
maxReplans: 3,
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/core/workflows/goal-engine/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmFH,MAAM,CAAC,MAAM,mBAAmB,GAAe;IAC9C,QAAQ,EAAE,EAAE;IACZ,eAAe,EAAE,CAAC;IAClB,QAAQ,EAAE,IAAI;IACd,WAAW,EAAE,IAAI;IACjB,UAAU,EAAE,IAAI;IAChB,SAAS,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,CAAC;IACnF,UAAU,EAAE,CAAC;CACb,CAAC","sourcesContent":["/**\n * Ada Intelligence Engine — Goal Engine (Fase 4).\n *\n * Tipos del bucle de trabajo autónomo: contrato primero (pi-until-done),\n * fases TDD fijas (pi-task), juez LLM obligatorio, frenos (pi-goal),\n * checklist persistente, ask_user_question (pi-ask-user).\n */\n\nexport type GoalPhase = \"analysis\" | \"bootstrap\" | \"red\" | \"green\" | \"refactor\" | \"verify\" | \"working\" | \"done\";\n\nexport type GoalStatus =\n\t| \"setup\" // contrato creado, pendiente de approve\n\t| \"planning\" // contrato aprobado, planificando tareas\n\t| \"active\" // bucle corriendo\n\t| \"paused\" // pausado por freno/usuario\n\t| \"blocked\" // bloqueado (esperando input)\n\t| \"usage_limited\" // token budget agotado\n\t| \"budget_limited\" // coste agotado\n\t| \"complete\";\n\nexport type TaskStatus = \"pending\" | \"active\" | \"running\" | \"done\" | \"failed\" | \"blocked\";\n\nexport interface Task {\n\tid: string;\n\ttitle: string;\n\tstatus: TaskStatus;\n\tdetail?: string;\n\t/** runId del workflow dinámico que ejecuta esta sub-tarea (goal-contenedor). */\n\tworkflowRunId?: string;\n\t/** Resultado resumido del workflow (lo lee el juez). */\n\tresultSummary?: string;\n}\n\nexport interface EvidenceItem {\n\tclaim: string;\n\tsource: string; // file:line | url | comando\n\tcitedBy: string; // quién la cita (agente/fase)\n}\n\nexport type JudgeVerdict = \"done\" | \"continue\";\n\n/** Registro de una iteración completa del goal (historial P3). */\nexport interface GoalIterationRecord {\n\titeration: number;\n\t/** Snapshot del plan (sub-tareas) de esa iteración. */\n\tplan: Task[];\n\t/** Veredicto del juez al cierre de la iteración (si llegó). */\n\tverdict?: JudgeVerdict;\n\t/** Razón del juez / motivo de replan. */\n\treason?: string;\n\t/** Motivo de la re-planificación (si la hubo). */\n\treplanRationale?: string;\n\ttokensUsed: number;\n\tcostUsed: number;\n\ttimestamp: string;\n}\n\nexport interface JudgeResult {\n\tverdict: JudgeVerdict;\n\treason: string;\n\t/** true si el juez se ejecutó con un modelo distinto al que trabaja. */\n\tcrossModel: boolean;\n}\n\nexport interface AskUserQuestion {\n\tid: string;\n\tquestion: string;\n\ttype: \"single-select\" | \"multi-select\" | \"freeform\";\n\tchoices?: string[];\n\trequired?: boolean;\n}\n\nexport interface GoalFrenos {\n\t/** Número máximo de turnos del bucle (pi-goal: 25 por defecto). */\n\tmaxTurns: number;\n\t/** Turnos vacíos/idénticos consecutivos que disparan pause (3). */\n\trepeatTolerance: number;\n\t/** Ruta del stop-file global (~/.ada-stop). null = desactivado. */\n\tstopFile: string | null;\n\t/** Presupuesto de tokens; null = sin límite. */\n\ttokenBudget: number | null;\n\t/** Presupuesto de coste $; null = sin límite. */\n\tcostBudget: number | null;\n\t/** Decisiones irreversibles que requieren confirmación del usuario. */\n\taskBefore: string[];\n\t/** Máximo de re-planificaciones completas antes de pausar (P1, default 3). */\n\tmaxReplans?: number;\n}\n\nexport const DEFAULT_GOAL_FRENOS: GoalFrenos = {\n\tmaxTurns: 25,\n\trepeatTolerance: 3,\n\tstopFile: null,\n\ttokenBudget: null,\n\tcostBudget: null,\n\taskBefore: [\"publish\", \"release\", \"delete\", \"rm -rf\", \"drop table\", \"spend\", \"buy\"],\n\tmaxReplans: 3,\n};\n\n/** Estado del goal — una instancia se rota (nuevo id) al editar/reanudar. */\nexport interface GoalState {\n\t/** Rotado al editar/reanudar: un turno viejo no puede completar el goal nuevo. */\n\tid: string;\n\t/** Sesión que creó el goal (para filtrar por conversación en el panel). */\n\tsessionId?: string;\n\tgoal: string; // verbatim\n\tphase: GoalPhase;\n\tstatus: GoalStatus;\n\t// ── contrato (pi-until-done) ──\n\tdoneCriteria: string[];\n\tverifyCommand: string;\n\t// ── plan ──\n\ttasks: Task[];\n\t// ── iteraciones (P3): historial completo de replans/veredictos ──\n\titeration: number; // actual (1-indexed)\n\titerations: GoalIterationRecord[];\n\treplanRationale?: string; // último motivo de re-planificación\n\t// ── evidencia y juez ──\n\tevidence: EvidenceItem[];\n\tjudge: {\n\t\tmodel: \"cross\" | \"same\" | null;\n\t\tlastVerdict?: JudgeVerdict;\n\t\tlastReason?: string;\n\t};\n\t// ── presupuesto y frenos ──\n\tturnsUsed: number;\n\ttokensUsed: number;\n\tcostUsed: number;\n\trepeatedTurns: number;\n\tlastAgentSummary: string; // para el repeat detector\n\t/**\n\t * Huella del árbol de trabajo en el último FALLO. Si una sub-tarea vuelve a\n\t * fallar con la misma huella, el agente no cambió nada: no es un intento, es\n\t * el mismo intento. Ver `worktree-fingerprint.ts`.\n\t */\n\tlastFailureFingerprint?: string;\n\twaiting?: { reason: string; resumeAfterMs?: number };\n\tpendingQuestions?: AskUserQuestion[];\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\n// ─── Acciones del reducer ───\n\nexport type GoalAction =\n\t| { type: \"goal_create\"; goal: string; doneCriteria: string[]; verifyCommand: string; sessionId?: string }\n\t| { type: \"goal_task_add\"; title: string }\n\t| { type: \"goal_approve\" }\n\t| { type: \"goal_tasks\"; tasks: Task[] }\n\t| { type: \"goal_task_update\"; taskId: string; status: TaskStatus }\n\t| { type: \"goal_task_launched\"; taskId: string; workflowRunId: string }\n\t| { type: \"goal_task_result\"; taskId: string; status: TaskStatus; summary?: string }\n\t| { type: \"goal_phase\"; phase: GoalPhase }\n\t| {\n\t\t\ttype: \"goal_agent_turn\";\n\t\t\tsummary: string;\n\t\t\tevidence?: EvidenceItem[];\n\t\t\ttokens?: number;\n\t\t\tcost?: number;\n\t\t\ttasks?: Array<{ taskId: string; status: TaskStatus }>;\n\t }\n\t| { type: \"goal_pause\"; reason?: string }\n\t| { type: \"goal_resume\" }\n\t| { type: \"goal_blocked\"; reason: string }\n\t| { type: \"goal_wait\"; reason: string; resumeAfterMs?: number }\n\t| { type: \"goal_questions\"; questions: AskUserQuestion[]; reason: string }\n\t| { type: \"goal_answers\"; answers: Record<string, string[]> }\n\t| { type: \"goal_usage_limited\" }\n\t| { type: \"goal_budget_limited\" }\n\t| { type: \"goal_judge\"; verdict: JudgeVerdict; reason: string; crossModel: boolean }\n\t| { type: \"goal_replan\"; tasks: Array<{ title: string }>; rationale?: string }\n\t| { type: \"goal_task_remove\"; taskId: string }\n\t| { type: \"goal_task_move\"; taskId: string; dir: \"up\" | \"down\" }\n\t| { type: \"goal_complete\"; summary: string; evidence: EvidenceItem[] };\n\n// ─── Eventos para la UI (Fase 5) ───\n\nexport interface GoalEventMap {\n\tgoal_update: { goal: GoalState; task?: Task };\n\tgoal_phase: { goalId: string; phase: GoalPhase };\n\tgoal_agent: { goalId: string; agent: { id: string; label: string; model?: string; detail?: string } };\n\tgoal_judge: { goalId: string; verdict: JudgeVerdict; reason: string };\n\tgoal_question: { goalId: string; questions: AskUserQuestion[] };\n\tgoal_finished: { goalId: string; status: GoalStatus; verdict?: JudgeVerdict };\n}\n\nexport type GoalEventType = keyof GoalEventMap;\nexport type GoalEventListener = <K extends GoalEventType>(type: K, payload: GoalEventMap[K]) => void;\n\n// ─── Interfaz del juez LLM (inyectable) ───\n\nexport type GoalJudgeFn = (input: {\n\tgoal: string;\n\tdoneCriteria: string[];\n\tverifyCommand: string;\n\tevidence: EvidenceItem[];\n\tphase: GoalPhase;\n}) => Promise<JudgeResult>;\n\n// ─── Interfaz de re-planificación (P1, inyectable) ───\n\nexport type GoalReplanFn = (input: {\n\tgoal: string;\n\tdoneCriteria: string[];\n\tverifyCommand: string;\n\tevidence: EvidenceItem[];\n\tcurrentTasks: Task[];\n\tlastVerdict?: JudgeVerdict;\n\tlastReason?: string;\n}) => Promise<{ tasks: Array<{ title: string }>; rationale?: string }>;\n\n// ─── Interfaz del agente de trabajo (inyectable) ───\n\nexport interface GoalWorkInput {\n\tgoal: string;\n\tphase: GoalPhase;\n\tdoneCriteria: string[];\n\tverifyCommand: string;\n\ttasks: Task[];\n\tevidence: EvidenceItem[];\n\tturn: number;\n\tmaxTurns: number;\n}\n\nexport interface GoalWorkResult {\n\tsummary: string;\n\tevidence?: EvidenceItem[];\n\ttokens?: number;\n\tcost?: number;\n\ttasks?: Array<{ taskId: string; status: TaskStatus }>;\n}\n\nexport type GoalWorkFn = (input: GoalWorkInput) => Promise<GoalWorkResult>;\n\n// ─── Persistencia (inyectable) ───\n\nexport interface GoalPersistence {\n\tsave(state: GoalState): Promise<void>;\n\tload(id: string): Promise<GoalState | null>;\n\tlist(): Promise<Array<{ id: string; goal: string; status: GoalStatus; phase: GoalPhase; updatedAt: string }>>;\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Huella del árbol de trabajo — detector de no-progreso para el Goal Engine.
|
|
3
|
+
*
|
|
4
|
+
* El fallo autónomo más caro no es equivocarse: es re-ejecutar el mismo verify
|
|
5
|
+
* contra un árbol idéntico y contarlo como intento. El repeat detector cuenta
|
|
6
|
+
* sub-tareas fallidas consecutivas, pero nada observaba si el trabajo cambió
|
|
7
|
+
* algo. Un agente puede "fallar" tres veces sin haber tocado un solo byte.
|
|
8
|
+
*
|
|
9
|
+
* Esto compara el estado observable del repo entre fallo y fallo. Si no cambió,
|
|
10
|
+
* el problema no es el intento: es el plan — así que el goal se pausa y el
|
|
11
|
+
* motivo entra en el prompt de re-planificación en vez de gastar otro turno.
|
|
12
|
+
*
|
|
13
|
+
* Fail-open: fuera de un repo git devuelve undefined y todo sigue igual.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Huella del estado observable del árbol: qué ficheros están modificados, el
|
|
17
|
+
* diff de los tracked, y el contenido de los untracked.
|
|
18
|
+
*
|
|
19
|
+
* `--porcelain=v1 -z -uall` respeta .gitignore, así que node_modules y
|
|
20
|
+
* artefactos de build no entran.
|
|
21
|
+
*/
|
|
22
|
+
export declare function workspaceFingerprint(cwd: string): Promise<string | undefined>;
|
|
23
|
+
//# sourceMappingURL=worktree-fingerprint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree-fingerprint.d.ts","sourceRoot":"","sources":["../../../../src/core/workflows/goal-engine/worktree-fingerprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAYH;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAwCnF","sourcesContent":["/**\n * Huella del árbol de trabajo — detector de no-progreso para el Goal Engine.\n *\n * El fallo autónomo más caro no es equivocarse: es re-ejecutar el mismo verify\n * contra un árbol idéntico y contarlo como intento. El repeat detector cuenta\n * sub-tareas fallidas consecutivas, pero nada observaba si el trabajo cambió\n * algo. Un agente puede \"fallar\" tres veces sin haber tocado un solo byte.\n *\n * Esto compara el estado observable del repo entre fallo y fallo. Si no cambió,\n * el problema no es el intento: es el plan — así que el goal se pausa y el\n * motivo entra en el prompt de re-planificación en vez de gastar otro turno.\n *\n * Fail-open: fuera de un repo git devuelve undefined y todo sigue igual.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { promisify } from \"node:util\";\n\n// execFile (sin shell): argumentos en array, nada se interpola en una cadena.\nconst execFileAsync = promisify(execFile);\n\n/** Techo de bytes hasheados de untracked; evita O(worktree) en repos enormes. */\nconst MAX_UNTRACKED_BYTES = 2 * 1024 * 1024;\n\n/**\n * Huella del estado observable del árbol: qué ficheros están modificados, el\n * diff de los tracked, y el contenido de los untracked.\n *\n * `--porcelain=v1 -z -uall` respeta .gitignore, así que node_modules y\n * artefactos de build no entran.\n */\nexport async function workspaceFingerprint(cwd: string): Promise<string | undefined> {\n\ttry {\n\t\tconst [status, diff] = await Promise.all([\n\t\t\texecFileAsync(\"git\", [\"-C\", cwd, \"status\", \"--porcelain=v1\", \"-z\", \"-uall\"], {\n\t\t\t\tmaxBuffer: 32 * 1024 * 1024,\n\t\t\t}),\n\t\t\texecFileAsync(\"git\", [\"-C\", cwd, \"diff\", \"HEAD\"], { maxBuffer: 32 * 1024 * 1024 }),\n\t\t]);\n\t\tconst hash = createHash(\"sha256\");\n\t\thash.update(status.stdout);\n\t\thash.update(diff.stdout);\n\n\t\t// El status ya nombra los untracked, pero no su contenido: un agente que\n\t\t// reescribe un fichero nuevo cambiaría nada del status. Hasheamos también\n\t\t// el contenido, con tope.\n\t\tconst untracked = status.stdout\n\t\t\t.split(\"\\0\")\n\t\t\t.filter((entry) => entry.startsWith(\"?? \"))\n\t\t\t.map((entry) => entry.slice(3));\n\t\tlet budget = MAX_UNTRACKED_BYTES;\n\t\tconst { readFile } = await import(\"node:fs/promises\");\n\t\tconst { join } = await import(\"node:path\");\n\t\tfor (const rel of untracked.sort()) {\n\t\t\tif (budget <= 0) break;\n\t\t\ttry {\n\t\t\t\tconst buf = await readFile(join(cwd, rel));\n\t\t\t\tconst slice = buf.subarray(0, budget);\n\t\t\t\tbudget -= slice.byteLength;\n\t\t\t\thash.update(rel);\n\t\t\t\thash.update(slice);\n\t\t\t} catch {\n\t\t\t\t// directorio, symlink roto, permisos — el nombre ya cuenta\n\t\t\t\thash.update(rel);\n\t\t\t}\n\t\t}\n\t\treturn hash.digest(\"hex\");\n\t} catch {\n\t\t// No es un repo git, o git no está disponible: fail-open.\n\t\treturn undefined;\n\t}\n}\n"]}
|