@hassangameryt/freeflow 0.5.0 → 0.7.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +4 -5
- package/README.md +141 -163
- package/capabilities/cognitive-routing/SKILL.md +387 -0
- package/capabilities/context-virtualization/SKILL.md +103 -0
- package/capabilities/conversation-history/SKILL.md +53 -0
- package/command-surface.json +6 -37
- package/hooks/freeflow-runtime-context.mjs +50 -541
- package/hooks/hooks.json +1 -26
- package/hooks/tests/check-runtime-context-hook.sh +114 -308
- package/package.json +27 -17
- package/pi-extension/dist/cognitive-routing/commands.js +96 -0
- package/pi-extension/dist/cognitive-routing/config.js +232 -0
- package/pi-extension/dist/cognitive-routing/controller.js +1292 -0
- package/pi-extension/dist/cognitive-routing/history.js +451 -0
- package/pi-extension/dist/cognitive-routing/host.js +188 -0
- package/pi-extension/dist/cognitive-routing/pi-routing-session.js +414 -0
- package/pi-extension/dist/cognitive-routing/pi-session-control.js +320 -0
- package/pi-extension/dist/cognitive-routing/runtime.js +43 -0
- package/pi-extension/dist/cognitive-routing/tool.js +212 -0
- package/pi-extension/dist/cognitive-routing/types.js +6 -0
- package/pi-extension/dist/context-virtualization/commands.js +89 -0
- package/pi-extension/dist/context-virtualization/projector.js +42 -0
- package/pi-extension/dist/context-virtualization/runtime.js +356 -0
- package/pi-extension/dist/context-virtualization/state.js +57 -0
- package/pi-extension/dist/context-virtualization/types.js +10 -0
- package/pi-extension/dist/conversation-history/passages.js +66 -0
- package/pi-extension/dist/conversation-history/ranking.js +105 -0
- package/pi-extension/dist/conversation-history/runtime.js +226 -0
- package/pi-extension/dist/conversation-history/search.js +56 -0
- package/pi-extension/dist/conversation-history/types.js +1 -0
- package/pi-extension/dist/freeflow-context/resolver.js +120 -0
- package/pi-extension/dist/freeflow-context/runtime.js +80 -0
- package/pi-extension/dist/freeflow-context/source-projector.js +95 -0
- package/pi-extension/dist/freeflow-context/tool.js +308 -0
- package/pi-extension/dist/freeflow-context/types.js +12 -0
- package/pi-extension/dist/freeflow-context/visibility.js +28 -0
- package/pi-extension/dist/index.js +564 -129
- package/pi-extension/dist/runtime/runtime-context.js +357 -470
- package/pi-extension/dist/runtime/runtime-identity.js +5 -0
- package/pi-extension/dist/settings/settings-tui.js +78 -0
- package/pi-extension/dist/settings/settings-ui.js +572 -826
- package/pi-extension/dist/ui/text-component.js +57 -0
- package/pi-extension/src/cognitive-routing/commands.ts +129 -0
- package/pi-extension/src/cognitive-routing/config.ts +303 -0
- package/pi-extension/src/cognitive-routing/controller.ts +1628 -0
- package/pi-extension/src/cognitive-routing/history.ts +650 -0
- package/pi-extension/src/cognitive-routing/host.ts +266 -0
- package/pi-extension/src/cognitive-routing/pi-routing-session.ts +538 -0
- package/pi-extension/src/cognitive-routing/pi-session-control.ts +444 -0
- package/pi-extension/src/cognitive-routing/runtime.ts +57 -0
- package/pi-extension/src/cognitive-routing/tool.ts +273 -0
- package/pi-extension/src/cognitive-routing/types.ts +89 -0
- package/pi-extension/src/context-virtualization/commands.ts +111 -0
- package/pi-extension/src/context-virtualization/projector.ts +62 -0
- package/pi-extension/src/context-virtualization/runtime.ts +406 -0
- package/pi-extension/src/context-virtualization/state.ts +79 -0
- package/pi-extension/src/context-virtualization/types.ts +92 -0
- package/pi-extension/src/conversation-history/passages.ts +81 -0
- package/pi-extension/src/conversation-history/ranking.ts +155 -0
- package/pi-extension/src/conversation-history/runtime.ts +250 -0
- package/pi-extension/src/conversation-history/search.ts +79 -0
- package/pi-extension/src/conversation-history/types.ts +31 -0
- package/pi-extension/src/freeflow-context/resolver.ts +139 -0
- package/pi-extension/src/freeflow-context/runtime.ts +100 -0
- package/pi-extension/src/freeflow-context/source-projector.ts +106 -0
- package/pi-extension/src/freeflow-context/tool.ts +360 -0
- package/pi-extension/src/freeflow-context/types.ts +70 -0
- package/pi-extension/src/freeflow-context/visibility.ts +53 -0
- package/pi-extension/src/index.ts +597 -135
- package/pi-extension/src/runtime/runtime-context.ts +373 -491
- package/pi-extension/src/runtime/runtime-identity.ts +8 -0
- package/pi-extension/src/settings/settings-tui.ts +93 -0
- package/pi-extension/src/settings/settings-ui.ts +679 -910
- package/pi-extension/src/ui/text-component.ts +66 -0
- package/pi-extension/tests/cognitive-routing/commands.test.js +134 -0
- package/pi-extension/tests/cognitive-routing/controller.test.js +1128 -0
- package/pi-extension/tests/cognitive-routing/extension-lifecycle.test.js +1142 -0
- package/pi-extension/tests/cognitive-routing/history.test.js +274 -0
- package/pi-extension/tests/cognitive-routing/host-fixture.js +4 -0
- package/pi-extension/tests/cognitive-routing/host-identity.test.js +63 -0
- package/pi-extension/tests/cognitive-routing/pi-normal-lifecycle.test.js +434 -0
- package/pi-extension/tests/cognitive-routing/pi-session-control.test.js +174 -0
- package/pi-extension/tests/cognitive-routing/pi-session-history.test.js +91 -0
- package/pi-extension/tests/cognitive-routing/profile-resolution.test.js +279 -0
- package/pi-extension/tests/cognitive-routing/tool.test.js +230 -0
- package/pi-extension/tests/context-virtualization/extension.test.js +749 -0
- package/pi-extension/tests/context-virtualization/projector.test.js +110 -0
- package/pi-extension/tests/context-virtualization/runtime.test.js +216 -0
- package/pi-extension/tests/conversation-history/runtime.test.js +98 -0
- package/pi-extension/tests/conversation-history/search.test.js +97 -0
- package/pi-extension/tests/integration/mode-free-core.test.js +218 -0
- package/pi-extension/tests/integration/pi-extension.test.js +532 -3701
- package/pi-extension/tests/integration/prompt-architecture.test.js +350 -0
- package/pi-extension/tests/integration/unaffected-regressions.test.js +411 -0
- package/runtime/prompts/cognitive-routing.md +10 -0
- package/runtime/prompts/context-virtualization.md +3 -0
- package/runtime/prompts/conversation-history.md +3 -0
- package/runtime/prompts/core.md +84 -0
- package/runtime/prompts/interaction-contract.md +11 -0
- package/skills/action-selection/SKILL.md +140 -0
- package/skills/action-selection/references/trajectory-stalls.md +71 -0
- package/skills/bypass/SKILL.md +109 -38
- package/skills/commit-work/SKILL.md +94 -55
- package/skills/commit-work/references/git-state-edges.md +94 -0
- package/skills/commit-work/references/simple-push.md +92 -0
- package/skills/commit-work/references/staging-decisions.md +79 -46
- package/skills/decision-gate/SKILL.md +80 -22
- package/skills/design-for-depth/SKILL.md +206 -60
- package/skills/design-for-depth/references/design-pressure-signals.md +108 -240
- package/skills/design-for-depth/references/interface-design-loop.md +77 -97
- package/skills/design-for-depth/references/module-and-dependency-design.md +147 -0
- package/skills/design-for-depth/references/software-design-philosophy.md +128 -174
- package/skills/design-for-depth/references/state-and-failure-boundaries.md +136 -0
- package/skills/diagnose-failure/SKILL.md +200 -48
- package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +18 -6
- package/skills/diagnose-failure/references/{flaky-and-performance.md → flaky-and-performance-diagnosis.md} +13 -5
- package/skills/discuss/SKILL.md +119 -65
- package/skills/discuss/references/discussion-continuity.md +123 -0
- package/skills/evaluate-skill/SKILL.md +166 -52
- package/skills/evaluate-skill/references/{definition-schema.md → evaluation-definition-schema.md} +43 -3
- package/skills/evaluate-skill/references/evaluation-design.md +56 -30
- package/skills/evaluate-skill/references/execution-and-evidence.md +8 -3
- package/skills/evaluate-skill/references/review-and-revision.md +62 -21
- package/skills/evaluate-skill/scripts/lib/definitions.mjs +114 -3
- package/skills/evaluate-skill/scripts/lib/grade-interaction.mjs +156 -1
- package/skills/evaluate-skill/scripts/lib/grade.mjs +9 -1
- package/skills/evaluate-skill/scripts/lib/pi.mjs +147 -32
- package/skills/evaluate-skill/scripts/lib/rpc.mjs +4 -4
- package/skills/evaluate-skill/scripts/lib/runner.mjs +36 -14
- package/skills/evaluate-skill/scripts/lib/sandbox.mjs +92 -0
- package/skills/evaluate-skill/scripts/pi-guard.mjs +1 -1
- package/skills/evaluate-skill/scripts/pi-observer.mjs +66 -0
- package/skills/evaluate-skill/scripts/skill-eval.mjs +6 -5
- package/skills/execute-work/SKILL.md +99 -57
- package/skills/execute-work/references/code-practices.md +4 -4
- package/skills/execute-work/references/execute-work-edges.md +62 -0
- package/skills/finish-branch/SKILL.md +2 -2
- package/skills/finish-branch/references/integration-options.md +1 -1
- package/skills/handoff/SKILL.md +3 -3
- package/skills/launch-work/SKILL.md +1 -1
- package/skills/launch-work/references/launch-readiness.md +2 -2
- package/skills/migration-work/SKILL.md +2 -2
- package/skills/migration-work/references/migration-lifecycle.md +1 -1
- package/skills/release-work/SKILL.md +1 -1
- package/skills/release-work/references/release-evidence.md +1 -1
- package/skills/review-artifact/SKILL.md +129 -66
- package/skills/review-artifact/references/adjudicate-artifact-review.md +101 -0
- package/skills/review-artifact/references/independent-artifact-reviewer-contract.md +159 -0
- package/skills/review-work/SKILL.md +113 -68
- package/skills/review-work/references/adjudicate-work-review.md +97 -0
- package/skills/review-work/references/independent-work-reviewer-contract.md +139 -0
- package/skills/review-work/references/security-risk-lens.md +18 -16
- package/skills/setup-freeflow/SKILL.md +16 -17
- package/skills/setup-freeflow/references/activation-contract.md +24 -30
- package/skills/setup-freeflow/references/host-setup.md +6 -7
- package/skills/simplify-code/SKILL.md +97 -39
- package/skills/simplify-code/references/simplification-patterns.md +1 -1
- package/skills/tdd/SKILL.md +100 -53
- package/skills/tdd/references/test-design.md +3 -3
- package/skills/track-work/SKILL.md +195 -58
- package/skills/track-work/references/working-record-format.md +515 -0
- package/skills/track-work/scripts/lib/document.mjs +713 -0
- package/skills/track-work/scripts/lib/format.mjs +166 -0
- package/skills/track-work/scripts/lib/store.mjs +233 -0
- package/skills/track-work/scripts/lib/transitions.mjs +790 -0
- package/skills/track-work/scripts/lib/views.mjs +40 -0
- package/skills/track-work/scripts/working-record.mjs +316 -0
- package/skills/verify-work/SKILL.md +57 -19
- package/skills/verify-work/references/browser-runtime-evidence.md +2 -2
- package/skills/verify-work/references/integration-evidence.md +1 -7
- package/skills/verify-work/references/performance-evidence.md +2 -2
- package/skills/workflow/SKILL.md +137 -55
- package/skills/workflow/references/domain-skill-composition.md +26 -40
- package/skills/write-plan/SKILL.md +1 -1
- package/skills/write-skill/SKILL.md +218 -61
- package/skills/write-skill/references/activation-boundaries.md +63 -21
- package/skills/write-skill/references/agent-first-instructions.md +61 -27
- package/skills/write-skill/references/progressive-disclosure.md +97 -33
- package/skills/write-skill/references/skill-dependency-graphs.md +190 -0
- package/capabilities/output-router/SKILL.md +0 -206
- package/capabilities/output-router/references/safety-policy.md +0 -40
- package/capabilities/output-router/references/setup.md +0 -110
- package/pi-extension/dist/output-router/host-producer-identification.js +0 -232
- package/pi-extension/dist/output-router/native-safety-net.js +0 -216
- package/pi-extension/dist/output-router/observed-tool-routing.js +0 -122
- package/pi-extension/dist/output-router/renderers.js +0 -1023
- package/pi-extension/dist/output-router/router-tools.js +0 -554
- package/pi-extension/dist/output-router/schemas.js +0 -383
- package/pi-extension/dist/output-router/status.js +0 -744
- package/pi-extension/dist/output-router/utils.js +0 -502
- package/pi-extension/src/output-router/host-producer-identification.ts +0 -256
- package/pi-extension/src/output-router/native-safety-net.ts +0 -248
- package/pi-extension/src/output-router/observed-tool-routing.ts +0 -134
- package/pi-extension/src/output-router/renderers.ts +0 -1108
- package/pi-extension/src/output-router/router-tools.ts +0 -579
- package/pi-extension/src/output-router/schemas.ts +0 -387
- package/pi-extension/src/output-router/status.ts +0 -791
- package/pi-extension/src/output-router/utils.ts +0 -554
- package/pi-extension/tests/output-router/observed-producers.test.js +0 -132
- package/pi-extension/tests/output-router/search.test.js +0 -722
- package/router/dist/benchmarks/benchmark-harness.d.ts +0 -35
- package/router/dist/benchmarks/benchmark-harness.js +0 -92
- package/router/dist/benchmarks/benchmarks.d.ts +0 -109
- package/router/dist/benchmarks/benchmarks.js +0 -979
- package/router/dist/benchmarks/codex-qa-benchmarks.d.ts +0 -95
- package/router/dist/benchmarks/codex-qa-benchmarks.js +0 -500
- package/router/dist/benchmarks/command-benchmarks.d.ts +0 -143
- package/router/dist/benchmarks/command-benchmarks.js +0 -698
- package/router/dist/benchmarks/context-mode-normalized-benchmarks.d.ts +0 -82
- package/router/dist/benchmarks/context-mode-normalized-benchmarks.js +0 -773
- package/router/dist/benchmarks/context-mode-real-deep-benchmark.d.ts +0 -132
- package/router/dist/benchmarks/context-mode-real-deep-benchmark.js +0 -1380
- package/router/dist/benchmarks/context-saving-baseline.d.ts +0 -60
- package/router/dist/benchmarks/context-saving-baseline.js +0 -470
- package/router/dist/benchmarks/index-benchmarks.d.ts +0 -103
- package/router/dist/benchmarks/index-benchmarks.js +0 -862
- package/router/dist/benchmarks/storage-policy-benchmarks.d.ts +0 -101
- package/router/dist/benchmarks/storage-policy-benchmarks.js +0 -618
- package/router/dist/benchmarks/vault-index-benchmarks.d.ts +0 -56
- package/router/dist/benchmarks/vault-index-benchmarks.js +0 -322
- package/router/dist/config/config.d.ts +0 -103
- package/router/dist/config/config.js +0 -632
- package/router/dist/config/router-contract.d.ts +0 -10
- package/router/dist/config/router-contract.js +0 -54
- package/router/dist/config/schema.d.ts +0 -27
- package/router/dist/config/schema.js +0 -648
- package/router/dist/config/types.d.ts +0 -573
- package/router/dist/config/types.js +0 -41
- package/router/dist/evidence/bounded-evidence.d.ts +0 -40
- package/router/dist/evidence/bounded-evidence.js +0 -323
- package/router/dist/evidence/evidence-range-selector.d.ts +0 -24
- package/router/dist/evidence/evidence-range-selector.js +0 -232
- package/router/dist/evidence/evidence-search.d.ts +0 -27
- package/router/dist/evidence/evidence-search.js +0 -490
- package/router/dist/evidence/evidence.d.ts +0 -38
- package/router/dist/evidence/evidence.js +0 -200
- package/router/dist/evidence/failure-contracts.d.ts +0 -37
- package/router/dist/evidence/failure-contracts.js +0 -166
- package/router/dist/evidence/line-ranges.d.ts +0 -24
- package/router/dist/evidence/line-ranges.js +0 -22
- package/router/dist/experiments/local-index.d.ts +0 -64
- package/router/dist/experiments/local-index.js +0 -581
- package/router/dist/index.d.ts +0 -30
- package/router/dist/index.js +0 -32
- package/router/dist/local/local-traversal.d.ts +0 -18
- package/router/dist/local/local-traversal.js +0 -334
- package/router/dist/processing/engine.d.ts +0 -132
- package/router/dist/processing/engine.js +0 -533
- package/router/dist/processing/reducers.d.ts +0 -280
- package/router/dist/processing/reducers.js +0 -1673
- package/router/dist/processing/renderers.d.ts +0 -31
- package/router/dist/processing/renderers.js +0 -195
- package/router/dist/processing/scripts.d.ts +0 -91
- package/router/dist/processing/scripts.js +0 -386
- package/router/dist/repo/repo-traversal.d.ts +0 -18
- package/router/dist/repo/repo-traversal.js +0 -245
- package/router/dist/routing/observed-reducers.d.ts +0 -41
- package/router/dist/routing/observed-reducers.js +0 -661
- package/router/dist/routing/observed-routing.d.ts +0 -26
- package/router/dist/routing/observed-routing.js +0 -378
- package/router/dist/routing/parsers.d.ts +0 -16
- package/router/dist/routing/parsers.js +0 -521
- package/router/dist/routing/run-filters.d.ts +0 -60
- package/router/dist/routing/run-filters.js +0 -238
- package/router/dist/routing/run-reducers.d.ts +0 -49
- package/router/dist/routing/run-reducers.js +0 -122
- package/router/dist/sandbox/adapter-roots.d.ts +0 -46
- package/router/dist/sandbox/adapter-roots.js +0 -66
- package/router/dist/sandbox/eryx-python-adapter.d.ts +0 -13
- package/router/dist/sandbox/eryx-python-adapter.js +0 -868
- package/router/dist/sandbox/jq-wasm-adapter.d.ts +0 -9
- package/router/dist/sandbox/jq-wasm-adapter.js +0 -429
- package/router/dist/sandbox/quickjs-wasi-adapter.d.ts +0 -13
- package/router/dist/sandbox/quickjs-wasi-adapter.js +0 -384
- package/router/dist/sandbox/script-sandbox.d.ts +0 -134
- package/router/dist/sandbox/script-sandbox.js +0 -337
- package/router/dist/setup/script-transform-adapters.d.ts +0 -32
- package/router/dist/setup/script-transform-adapters.js +0 -278
- package/router/dist/tools/batch.d.ts +0 -33
- package/router/dist/tools/batch.js +0 -586
- package/router/dist/tools/run.d.ts +0 -62
- package/router/dist/tools/run.js +0 -1304
- package/router/dist/tools/search.d.ts +0 -66
- package/router/dist/tools/search.js +0 -1364
- package/router/dist/transform/engine.d.ts +0 -168
- package/router/dist/transform/engine.js +0 -2072
- package/router/dist/vault/vault-index.d.ts +0 -125
- package/router/dist/vault/vault-index.js +0 -416
- package/router/dist/vault/vault.d.ts +0 -138
- package/router/dist/vault/vault.js +0 -630
- package/runtime/interaction-contract.md +0 -16
- package/skills/discuss/references/checkpoints.md +0 -66
- package/skills/execute-work/references/execution-loop.md +0 -77
- package/skills/mode-contract/SKILL.md +0 -104
- package/skills/review-artifact/references/reviewer-prompt.md +0 -148
- package/skills/review-work/references/reviewer-prompt.md +0 -134
- package/skills/track-work/references/working-record-schema.md +0 -378
- package/skills/workflow/references/workflow-loop.md +0 -92
- /package/skills/handoff/references/{templates.md → handoff-templates.md} +0 -0
|
@@ -1,35 +1,157 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
COGNITIVE_ROUTING_CONTROL_ENTRY,
|
|
3
|
+
COGNITIVE_ROUTING_INACTIVE_ENTRY,
|
|
4
|
+
COGNITIVE_ROUTING_INTENT_ENTRY,
|
|
5
|
+
} from "./cognitive-routing/controller.js";
|
|
6
|
+
import { PiRoutingSession } from "./cognitive-routing/pi-routing-session.js";
|
|
7
|
+
import {
|
|
8
|
+
cognitiveRoutingProfileCompletions,
|
|
9
|
+
handleCognitiveRoutingProfileCommand,
|
|
10
|
+
} from "./cognitive-routing/commands.js";
|
|
11
|
+
import { registerCognitiveRoutingHistoryTool, registerCognitiveRoutingTool } from "./cognitive-routing/tool.js";
|
|
12
|
+
import { readCognitiveRoutingHistory } from "./cognitive-routing/history.js";
|
|
13
|
+
import { ConversationHistoryRuntime } from "./conversation-history/runtime.js";
|
|
14
|
+
import { FreeflowContextRuntime } from "./freeflow-context/runtime.js";
|
|
15
|
+
import { CONTEXT_VIRTUALIZATION_TOOL_NAME, registerFreeflowContextTool } from "./freeflow-context/tool.js";
|
|
16
|
+
import { handleContextCommand } from "./context-virtualization/commands.js";
|
|
17
|
+
import { ContextVirtualizationRuntime } from "./context-virtualization/runtime.js";
|
|
18
|
+
import { handleFreeflowCommand } from "./settings/settings-ui.js";
|
|
19
|
+
import { isPiFlowHost } from "./runtime/runtime-identity.js";
|
|
5
20
|
import {
|
|
6
21
|
CONTRIBUTOR_COMMANDS,
|
|
22
|
+
COGNITIVE_ROUTING_SWITCH_TOOL_NAME,
|
|
7
23
|
WORKFLOW_COMMANDS,
|
|
8
|
-
WORKFLOW_BOOTSTRAP_MESSAGE_TYPE,
|
|
9
|
-
FREEFLOW_STATUS_TOOL_NAME,
|
|
10
24
|
freeflowModelSkillPaths,
|
|
11
25
|
freeflowSkillPath,
|
|
12
26
|
getRuntimeContext,
|
|
13
|
-
|
|
27
|
+
hasUsableMandatoryPrompts,
|
|
28
|
+
isPromptAvailable,
|
|
14
29
|
readCapabilityState,
|
|
15
|
-
readModeState,
|
|
16
|
-
readOutputRouterConfig,
|
|
17
30
|
refreshRuntimeContext,
|
|
18
|
-
|
|
31
|
+
restoreSessionOverrides,
|
|
19
32
|
runtimeContext,
|
|
20
|
-
|
|
21
|
-
|
|
33
|
+
filterBootstrapMessage,
|
|
34
|
+
setFreeflowStatus,
|
|
22
35
|
skillPrompt,
|
|
23
|
-
|
|
36
|
+
withFreeflowRuntimeState,
|
|
24
37
|
} from "./runtime/runtime-context.js";
|
|
25
|
-
function
|
|
26
|
-
return
|
|
38
|
+
function unavailableCapability(capability, code, message) {
|
|
39
|
+
return {
|
|
40
|
+
...capability,
|
|
41
|
+
effective: false,
|
|
42
|
+
blockingReason: { code, message },
|
|
43
|
+
};
|
|
27
44
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
45
|
+
function modelFacingCapabilityState(
|
|
46
|
+
capabilityState,
|
|
47
|
+
freeflowContext,
|
|
48
|
+
routingSnapshot,
|
|
49
|
+
cognitiveRoutingActivationFailed = false,
|
|
50
|
+
) {
|
|
51
|
+
const surfaceState = {
|
|
52
|
+
...capabilityState,
|
|
53
|
+
contextVirtualization: { ...capabilityState?.contextVirtualization },
|
|
54
|
+
conversationHistory: { ...capabilityState?.conversationHistory },
|
|
55
|
+
cognitiveRouting: { ...capabilityState?.cognitiveRouting },
|
|
56
|
+
};
|
|
57
|
+
if (surfaceState.enabled !== true) return surfaceState;
|
|
58
|
+
const markUnavailable = (key, message) => {
|
|
59
|
+
if (surfaceState[key]?.effective === true) {
|
|
60
|
+
surfaceState[key] = unavailableCapability(surfaceState[key], "unavailable", message);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
if (!hasUsableMandatoryPrompts(freeflowContext)) {
|
|
64
|
+
for (const key of ["contextVirtualization", "conversationHistory", "cognitiveRouting"]) {
|
|
65
|
+
markUnavailable(key, "Mandatory Freeflow prompt is unavailable.");
|
|
66
|
+
}
|
|
67
|
+
return surfaceState;
|
|
68
|
+
}
|
|
69
|
+
if (
|
|
70
|
+
surfaceState.contextVirtualization?.effective === true &&
|
|
71
|
+
!isPromptAvailable(freeflowContext.contextVirtualizationPrompt)
|
|
72
|
+
) {
|
|
73
|
+
markUnavailable("contextVirtualization", "Context Virtualization prompt is unavailable.");
|
|
31
74
|
}
|
|
32
|
-
|
|
75
|
+
if (
|
|
76
|
+
surfaceState.conversationHistory?.effective === true &&
|
|
77
|
+
!isPromptAvailable(freeflowContext.conversationHistoryPrompt)
|
|
78
|
+
) {
|
|
79
|
+
markUnavailable("conversationHistory", "Conversation History prompt is unavailable.");
|
|
80
|
+
}
|
|
81
|
+
if (surfaceState.cognitiveRouting?.effective === true) {
|
|
82
|
+
const controllerState = routingSnapshot.runtimeState;
|
|
83
|
+
if (routingSnapshot.disposition === "blocked") {
|
|
84
|
+
surfaceState.cognitiveRouting = unavailableCapability(
|
|
85
|
+
surfaceState.cognitiveRouting,
|
|
86
|
+
"runtime_blocked",
|
|
87
|
+
routingSnapshot.reason ?? "Cognitive Routing is blocked because its inactive state could not be persisted.",
|
|
88
|
+
);
|
|
89
|
+
} else if (routingSnapshot.startupSelectionSuppressed || routingSnapshot.disposition === "inactive") {
|
|
90
|
+
surfaceState.cognitiveRouting = unavailableCapability(
|
|
91
|
+
surfaceState.cognitiveRouting,
|
|
92
|
+
"runtime_inactive",
|
|
93
|
+
"Cognitive Routing is inactive because Pi owns the startup model or thinking level.",
|
|
94
|
+
);
|
|
95
|
+
} else if (controllerState?.runtimeStatus === "inactive") {
|
|
96
|
+
surfaceState.cognitiveRouting = unavailableCapability(
|
|
97
|
+
surfaceState.cognitiveRouting,
|
|
98
|
+
"runtime_inactive",
|
|
99
|
+
controllerState.runtimeReason ?? "Cognitive Routing is inactive because Pi owns the current model state.",
|
|
100
|
+
);
|
|
101
|
+
} else if (controllerState?.runtimeStatus === "blocked") {
|
|
102
|
+
surfaceState.cognitiveRouting = unavailableCapability(
|
|
103
|
+
surfaceState.cognitiveRouting,
|
|
104
|
+
"runtime_blocked",
|
|
105
|
+
controllerState.runtimeReason ?? "Cognitive Routing is blocked because its state is not proven.",
|
|
106
|
+
);
|
|
107
|
+
} else if (cognitiveRoutingActivationFailed || controllerState?.effective === false) {
|
|
108
|
+
surfaceState.cognitiveRouting = unavailableCapability(
|
|
109
|
+
surfaceState.cognitiveRouting,
|
|
110
|
+
"unavailable",
|
|
111
|
+
"Cognitive Routing could not activate for this session.",
|
|
112
|
+
);
|
|
113
|
+
} else if (!isPromptAvailable(freeflowContext.cognitiveRoutingPrompt)) {
|
|
114
|
+
markUnavailable("cognitiveRouting", "Cognitive Routing prompt is unavailable.");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return surfaceState;
|
|
118
|
+
}
|
|
119
|
+
function sessionHasConversationOrRoutingState(ctx) {
|
|
120
|
+
try {
|
|
121
|
+
const entries = ctx?.sessionManager?.getBranch?.() ?? ctx?.sessionManager?.getEntries?.() ?? [];
|
|
122
|
+
if (!Array.isArray(entries)) return false;
|
|
123
|
+
return entries.some((entry) => {
|
|
124
|
+
if (!entry || typeof entry !== "object") return false;
|
|
125
|
+
const record = entry;
|
|
126
|
+
if (
|
|
127
|
+
typeof record.type === "string" &&
|
|
128
|
+
["message", "custom_message", "compaction", "branch_summary"].includes(record.type)
|
|
129
|
+
) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return (
|
|
133
|
+
record.type === "custom" &&
|
|
134
|
+
(record.customType === COGNITIVE_ROUTING_INTENT_ENTRY ||
|
|
135
|
+
record.customType === COGNITIVE_ROUTING_CONTROL_ENTRY ||
|
|
136
|
+
record.customType === COGNITIVE_ROUTING_INACTIVE_ENTRY)
|
|
137
|
+
);
|
|
138
|
+
});
|
|
139
|
+
} catch {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async function applyCapabilityToolVisibility(
|
|
144
|
+
pi,
|
|
145
|
+
ctx,
|
|
146
|
+
capabilityState = undefined,
|
|
147
|
+
routingSnapshot = {
|
|
148
|
+
status: "available",
|
|
149
|
+
disposition: "available",
|
|
150
|
+
startupSelectionSuppressed: false,
|
|
151
|
+
},
|
|
152
|
+
) {
|
|
153
|
+
if (typeof pi?.setActiveTools !== "function" || typeof pi?.getAllTools !== "function") return;
|
|
154
|
+
const state = capabilityState ?? (await readCapabilityState(ctx.cwd, ctx, pi?.host));
|
|
33
155
|
const allToolNames = pi
|
|
34
156
|
.getAllTools()
|
|
35
157
|
.map((tool) => tool?.name)
|
|
@@ -39,23 +161,24 @@ async function applyCapabilityToolVisibility(pi, ctx, capabilityState = undefine
|
|
|
39
161
|
const active = new Set(
|
|
40
162
|
(Array.isArray(currentActive) ? currentActive : allToolNames).filter((name) => allToolNameSet.has(name)),
|
|
41
163
|
);
|
|
42
|
-
if (allToolNameSet.has(
|
|
43
|
-
|
|
44
|
-
|
|
164
|
+
if (allToolNameSet.has(COGNITIVE_ROUTING_SWITCH_TOOL_NAME)) {
|
|
165
|
+
const controllerState = routingSnapshot.runtimeState;
|
|
166
|
+
const routingToolActive =
|
|
167
|
+
state.cognitiveRouting?.effective === true &&
|
|
168
|
+
controllerState?.effective === true &&
|
|
169
|
+
controllerState.controlMode === "automatic";
|
|
170
|
+
if (routingToolActive) active.add(COGNITIVE_ROUTING_SWITCH_TOOL_NAME);
|
|
171
|
+
else active.delete(COGNITIVE_ROUTING_SWITCH_TOOL_NAME);
|
|
45
172
|
}
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
else
|
|
173
|
+
if (allToolNameSet.has(CONTEXT_VIRTUALIZATION_TOOL_NAME)) {
|
|
174
|
+
if (state.contextVirtualization?.effective === true || state.conversationHistory?.effective === true) {
|
|
175
|
+
active.add(CONTEXT_VIRTUALIZATION_TOOL_NAME);
|
|
176
|
+
} else {
|
|
177
|
+
active.delete(CONTEXT_VIRTUALIZATION_TOOL_NAME);
|
|
178
|
+
}
|
|
50
179
|
}
|
|
51
180
|
pi.setActiveTools([...active]);
|
|
52
181
|
}
|
|
53
|
-
async function applyLiveCapabilityState(pi, ctx) {
|
|
54
|
-
const [modeState, capabilityState] = await Promise.all([readModeState(ctx.cwd), readCapabilityState(ctx.cwd)]);
|
|
55
|
-
await refreshRuntimeContext(capabilityState);
|
|
56
|
-
setModeStatus(ctx, modeState, capabilityState);
|
|
57
|
-
await applyCapabilityToolVisibility(pi, ctx, capabilityState);
|
|
58
|
-
}
|
|
59
182
|
function disabledToolCall(toolName, capability) {
|
|
60
183
|
const command = capability === "freeflow" ? "/freeflow settings" : `/${capability} settings`;
|
|
61
184
|
return {
|
|
@@ -63,16 +186,7 @@ function disabledToolCall(toolName, capability) {
|
|
|
63
186
|
reason: `${toolName} is disabled by Freeflow config. Configure ${capability} with ${command}.`,
|
|
64
187
|
};
|
|
65
188
|
}
|
|
66
|
-
function
|
|
67
|
-
const query = prefix ?? "";
|
|
68
|
-
return [
|
|
69
|
-
{ value: "settings", label: "settings", description: "Open repository Output Router settings" },
|
|
70
|
-
{ value: "status", label: "status", description: "Show effective Output Router state" },
|
|
71
|
-
{ value: "enable", label: "enable", description: "Enable Output Router for this repository" },
|
|
72
|
-
{ value: "disable", label: "disable", description: "Disable Output Router for this repository" },
|
|
73
|
-
].filter((item) => item.value.startsWith(query));
|
|
74
|
-
}
|
|
75
|
-
function freeflowCompletions(prefix) {
|
|
189
|
+
function freeflowCompletions(prefix, cognitiveRoutingAvailable = false) {
|
|
76
190
|
const query = prefix ?? "";
|
|
77
191
|
if (query.startsWith("settings ")) {
|
|
78
192
|
const settingsQuery = query.slice("settings ".length);
|
|
@@ -84,25 +198,30 @@ function freeflowCompletions(prefix) {
|
|
|
84
198
|
.filter((item) => item.value.startsWith(settingsQuery))
|
|
85
199
|
.map((item) => ({ ...item, value: `settings ${item.value}` }));
|
|
86
200
|
}
|
|
87
|
-
if (query.startsWith("
|
|
88
|
-
|
|
201
|
+
if (cognitiveRoutingAvailable && query.startsWith("profile ")) {
|
|
202
|
+
return cognitiveRoutingProfileCompletions(query.slice("profile ".length)).map((item) => ({
|
|
203
|
+
...item,
|
|
204
|
+
value: `profile ${item.value}`,
|
|
205
|
+
}));
|
|
206
|
+
}
|
|
207
|
+
if (query.startsWith("context ")) {
|
|
208
|
+
const contextQuery = query.slice("context ".length);
|
|
89
209
|
return [
|
|
90
|
-
{ value: "
|
|
91
|
-
{ value: "
|
|
92
|
-
{ value: "
|
|
93
|
-
{
|
|
94
|
-
value: "reset",
|
|
95
|
-
label: "reset",
|
|
96
|
-
description: "Clear the session override and use the configured default",
|
|
97
|
-
},
|
|
210
|
+
{ value: "status", label: "status", description: "Show Freeflow Context state" },
|
|
211
|
+
{ value: "list", label: "list", description: "List archived context projections" },
|
|
212
|
+
{ value: "restore", label: "restore", description: "Restore one or more context references" },
|
|
213
|
+
{ value: "reset all", label: "reset all", description: "Reset projection decisions on the active branch" },
|
|
98
214
|
]
|
|
99
|
-
.filter((item) => item.value.startsWith(
|
|
100
|
-
.map((item) => ({ ...item, value: `
|
|
215
|
+
.filter((item) => item.value.startsWith(contextQuery))
|
|
216
|
+
.map((item) => ({ ...item, value: `context ${item.value}` }));
|
|
101
217
|
}
|
|
102
218
|
return [
|
|
103
219
|
{ value: "settings", label: "settings", description: "Open personal override settings" },
|
|
104
220
|
{ value: "status", label: "status", description: "Show effective Freeflow state" },
|
|
105
|
-
{ value: "
|
|
221
|
+
{ value: "context", label: "context", description: "Inspect Freeflow Context" },
|
|
222
|
+
...(cognitiveRoutingAvailable
|
|
223
|
+
? [{ value: "profile", label: "profile", description: "Hold or release Cognitive Routing profile control" }]
|
|
224
|
+
: []),
|
|
106
225
|
{ value: "enable", label: "enable", description: "Enable Freeflow for this repository" },
|
|
107
226
|
{ value: "disable", label: "disable", description: "Disable Freeflow for this repository" },
|
|
108
227
|
].filter((item) => item.value.startsWith(query));
|
|
@@ -115,9 +234,9 @@ function bypassCompletions(prefix) {
|
|
|
115
234
|
].filter((item) => item.value.startsWith(query));
|
|
116
235
|
}
|
|
117
236
|
async function sendSkillCommand(pi, ctx, skill, args) {
|
|
118
|
-
const state = await readCapabilityState(ctx.cwd);
|
|
237
|
+
const state = await readCapabilityState(ctx.cwd, ctx, pi?.host);
|
|
119
238
|
if (skill === "setup-freeflow" && !state.configured) {
|
|
120
|
-
await pi.sendUserMessage(skillPrompt(skill, args));
|
|
239
|
+
await pi.sendUserMessage(skillPrompt(skill, args), { expandPromptTemplates: true });
|
|
121
240
|
return;
|
|
122
241
|
}
|
|
123
242
|
if (!state.configured) {
|
|
@@ -131,100 +250,383 @@ async function sendSkillCommand(pi, ctx, skill, args) {
|
|
|
131
250
|
);
|
|
132
251
|
return;
|
|
133
252
|
}
|
|
134
|
-
|
|
135
|
-
|
|
253
|
+
const freeflowContext = await getRuntimeContext(state);
|
|
254
|
+
if (!hasUsableMandatoryPrompts(freeflowContext)) {
|
|
255
|
+
ctx.ui.notify("Freeflow core prompts are unavailable; the requested skill cannot be dispatched.", "warning");
|
|
136
256
|
return;
|
|
137
257
|
}
|
|
138
|
-
await pi.sendUserMessage(skillPrompt(skill, args));
|
|
258
|
+
await pi.sendUserMessage(skillPrompt(skill, args), { expandPromptTemplates: true });
|
|
139
259
|
}
|
|
140
260
|
export default function freeflow(pi) {
|
|
141
|
-
|
|
261
|
+
// SAFETY: These helpers register complete Pi tool definitions but retain legacy structural typing for PiFlow compatibility.
|
|
262
|
+
const toolRegistrar = pi;
|
|
263
|
+
const routingSession = new PiRoutingSession({ pi, stockPi: !isPiFlowHost(pi?.host) });
|
|
264
|
+
let latestCognitiveRoutingContext;
|
|
265
|
+
let providerSurfaceSnapshot;
|
|
266
|
+
let runtimeStateRefreshRequired = true;
|
|
267
|
+
let freeflowContextRuntime;
|
|
268
|
+
let contextVirtualizationRuntime;
|
|
269
|
+
let conversationHistoryRuntime;
|
|
270
|
+
const registerContextToolForState = (capabilityState) => {
|
|
271
|
+
registerFreeflowContextTool(
|
|
272
|
+
toolRegistrar,
|
|
273
|
+
() => contextVirtualizationRuntime,
|
|
274
|
+
() => conversationHistoryRuntime,
|
|
275
|
+
{
|
|
276
|
+
contextVirtualization: capabilityState?.contextVirtualization?.effective === true,
|
|
277
|
+
conversationHistory: capabilityState?.conversationHistory?.effective === true,
|
|
278
|
+
},
|
|
279
|
+
);
|
|
280
|
+
};
|
|
281
|
+
const buildProviderSurface = async (ctx, activateCognitiveRouting = false) => {
|
|
282
|
+
const capabilityState = await readCapabilityState(ctx.cwd, ctx, pi?.host);
|
|
283
|
+
const freeflowContext = await getRuntimeContext(capabilityState);
|
|
284
|
+
const promptCapabilityState = modelFacingCapabilityState(
|
|
285
|
+
capabilityState,
|
|
286
|
+
freeflowContext,
|
|
287
|
+
routingSession.snapshot(),
|
|
288
|
+
);
|
|
289
|
+
let activationAttempted = false;
|
|
290
|
+
if (
|
|
291
|
+
activateCognitiveRouting &&
|
|
292
|
+
routingSession.canAutoActivate() &&
|
|
293
|
+
(!routingSession.hasController() || promptCapabilityState.cognitiveRouting?.effective !== true)
|
|
294
|
+
) {
|
|
295
|
+
activationAttempted = promptCapabilityState.cognitiveRouting?.effective === true;
|
|
296
|
+
try {
|
|
297
|
+
await routingSession.reconcileController(
|
|
298
|
+
ctx,
|
|
299
|
+
promptCapabilityState,
|
|
300
|
+
routingSession.armed ? { ...routingSession.armed } : undefined,
|
|
301
|
+
);
|
|
302
|
+
if (routingSession.hasController()) {
|
|
303
|
+
routingSession.clearArmed();
|
|
304
|
+
if (routingSession.snapshot().status === "active") routingSession.markActive();
|
|
305
|
+
}
|
|
306
|
+
} catch {
|
|
307
|
+
routingSession.clearController();
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const surfaceCapabilityState = modelFacingCapabilityState(
|
|
311
|
+
promptCapabilityState,
|
|
312
|
+
freeflowContext,
|
|
313
|
+
routingSession.snapshot(),
|
|
314
|
+
activationAttempted && !routingSession.hasController(),
|
|
315
|
+
);
|
|
316
|
+
const routingSnapshot = routingSession.snapshot();
|
|
317
|
+
return {
|
|
318
|
+
capabilityState: surfaceCapabilityState,
|
|
319
|
+
freeflowContext,
|
|
320
|
+
cognitiveRoutingRuntime: routingSnapshot.runtimeState,
|
|
321
|
+
configuredCapabilityState: capabilityState,
|
|
322
|
+
};
|
|
323
|
+
};
|
|
324
|
+
const applyLiveCapabilityStateForSession = async (ctx, options = {}) => {
|
|
325
|
+
providerSurfaceSnapshot = undefined;
|
|
326
|
+
await routingSession.applyLiveCapabilityState(ctx, options);
|
|
327
|
+
const capabilityState = await readCapabilityState(ctx.cwd, ctx, pi?.host);
|
|
328
|
+
const freeflowContext = await getRuntimeContext(capabilityState);
|
|
329
|
+
const surfaceCapabilityState = modelFacingCapabilityState(
|
|
330
|
+
capabilityState,
|
|
331
|
+
freeflowContext,
|
|
332
|
+
routingSession.snapshot(),
|
|
333
|
+
);
|
|
334
|
+
const routingSnapshot = routingSession.snapshot();
|
|
335
|
+
setFreeflowStatus(ctx, surfaceCapabilityState, routingSnapshot.runtimeState, freeflowContext, {
|
|
336
|
+
startupSelectionSuppressed: routingSnapshot.startupSelectionSuppressed,
|
|
337
|
+
});
|
|
338
|
+
await applyCapabilityToolVisibility(pi, ctx, surfaceCapabilityState, routingSnapshot);
|
|
339
|
+
registerContextToolForState(surfaceCapabilityState);
|
|
340
|
+
};
|
|
341
|
+
if (routingSession.supportsCognitiveRoutingRuntime()) {
|
|
342
|
+
registerCognitiveRoutingTool(toolRegistrar, () => routingSession.controllerForTool());
|
|
343
|
+
registerCognitiveRoutingHistoryTool(toolRegistrar, (options, context) => {
|
|
344
|
+
return (
|
|
345
|
+
routingSession.history(options) ??
|
|
346
|
+
readCognitiveRoutingHistory(context ?? latestCognitiveRoutingContext, options)
|
|
347
|
+
);
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
registerFreeflowContextTool(
|
|
351
|
+
toolRegistrar,
|
|
352
|
+
() => contextVirtualizationRuntime,
|
|
353
|
+
() => conversationHistoryRuntime,
|
|
354
|
+
{ contextVirtualization: false, conversationHistory: false },
|
|
355
|
+
);
|
|
356
|
+
if (routingSession.supportsCognitiveRoutingRuntime() && typeof pi.registerShortcut === "function") {
|
|
357
|
+
pi.registerShortcut("ctrl+shift+r", {
|
|
358
|
+
description: "Cycle the Cognitive Routing manual standard/reasoning hold",
|
|
359
|
+
handler: async (ctx) => {
|
|
360
|
+
if (typeof ctx?.isIdle === "function" && !ctx.isIdle()) {
|
|
361
|
+
ctx.ui?.notify?.("Freeflow settings and profile changes are available only while Pi is idle.", "warning");
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
const armedCycle = routingSession.hasController() ? undefined : routingSession.cycleArmedManual();
|
|
365
|
+
if (armedCycle) {
|
|
366
|
+
routingSession.beginExplicitReactivation();
|
|
367
|
+
ctx.ui?.notify?.(`Cognitive Routing manual hold set to ${armedCycle.target}.`, "info");
|
|
368
|
+
await applyLiveCapabilityStateForSession(ctx, {
|
|
369
|
+
reconcileCognitiveRouting: true,
|
|
370
|
+
materializeCognitiveRouting: !isPiFlowHost(pi?.host),
|
|
371
|
+
});
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
if (!routingSession.hasController()) {
|
|
375
|
+
routingSession.beginExplicitReactivation();
|
|
376
|
+
await applyLiveCapabilityStateForSession(ctx, { reconcileCognitiveRouting: true });
|
|
377
|
+
}
|
|
378
|
+
const state = routingSession.snapshot().runtimeState;
|
|
379
|
+
if (!state) {
|
|
380
|
+
ctx.ui?.notify?.("Cognitive Routing is unavailable for this session.", "warning");
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
const target = state.activeProfile === "reasoning" ? "standard" : "reasoning";
|
|
384
|
+
const result = await routingSession.setManualProfile(target, "profile-shortcut");
|
|
385
|
+
if (result.status === "active") {
|
|
386
|
+
ctx.ui?.notify?.(`Cognitive Routing manual hold set to ${target}.`, "info");
|
|
387
|
+
} else {
|
|
388
|
+
ctx.ui?.notify?.(`Cognitive Routing could not set the manual profile: ${result.reason}.`, "warning");
|
|
389
|
+
}
|
|
390
|
+
await applyLiveCapabilityStateForSession(ctx);
|
|
391
|
+
},
|
|
392
|
+
});
|
|
393
|
+
pi.registerShortcut("ctrl+shift+a", {
|
|
394
|
+
description: "Set Cognitive Routing to automatic Reasoning control",
|
|
395
|
+
handler: async (ctx) => {
|
|
396
|
+
if (typeof ctx?.isIdle === "function" && !ctx.isIdle()) {
|
|
397
|
+
ctx.ui?.notify?.("Freeflow settings and profile changes are available only while Pi is idle.", "warning");
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
const armedCycle = routingSession.hasController() ? undefined : routingSession.cycleArmedAutomatic();
|
|
401
|
+
if (armedCycle) {
|
|
402
|
+
if (!armedCycle.changed) {
|
|
403
|
+
ctx.ui?.notify?.("Cognitive Routing automatic control active.", "info");
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
ctx.ui?.notify?.("Cognitive Routing automatic control active.", "info");
|
|
407
|
+
routingSession.beginExplicitReactivation();
|
|
408
|
+
await applyLiveCapabilityStateForSession(ctx, {
|
|
409
|
+
reconcileCognitiveRouting: true,
|
|
410
|
+
materializeCognitiveRouting: !isPiFlowHost(pi?.host),
|
|
411
|
+
});
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (!routingSession.hasController()) {
|
|
415
|
+
routingSession.beginExplicitReactivation();
|
|
416
|
+
await applyLiveCapabilityStateForSession(ctx, { reconcileCognitiveRouting: true });
|
|
417
|
+
}
|
|
418
|
+
const result = await routingSession.setAutomaticControl("profile-shortcut");
|
|
419
|
+
if (result.status === "automatic") {
|
|
420
|
+
ctx.ui?.notify?.("Cognitive Routing automatic control active.", "info");
|
|
421
|
+
} else {
|
|
422
|
+
ctx.ui?.notify?.(`Cognitive Routing could not change control: ${result.reason}.`, "warning");
|
|
423
|
+
}
|
|
424
|
+
await applyLiveCapabilityStateForSession(ctx);
|
|
425
|
+
},
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
if (!isPiFlowHost(pi?.host) && routingSession.supportsCognitiveRoutingRuntime()) {
|
|
429
|
+
pi.on("model_select", async (event, ctx) => {
|
|
430
|
+
if (!routingSession.hasController()) {
|
|
431
|
+
if (!routingSession.armed) return;
|
|
432
|
+
routingSession.clearArmed();
|
|
433
|
+
routingSession.observeArmedNativeChange(ctx, "Pi model selection");
|
|
434
|
+
await applyLiveCapabilityStateForSession(ctx);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
const result = await routingSession.observeNativeChange("Pi model selection", event?.source);
|
|
438
|
+
if (result.status !== "ignored") {
|
|
439
|
+
latestCognitiveRoutingContext = ctx;
|
|
440
|
+
providerSurfaceSnapshot = undefined;
|
|
441
|
+
await applyLiveCapabilityStateForSession(ctx);
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
pi.on("thinking_level_select", async (_event, ctx) => {
|
|
445
|
+
if (!routingSession.hasController()) {
|
|
446
|
+
if (!routingSession.armed) return;
|
|
447
|
+
routingSession.clearArmed();
|
|
448
|
+
routingSession.observeArmedNativeChange(ctx, "Pi thinking-level selection");
|
|
449
|
+
await applyLiveCapabilityStateForSession(ctx);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
const result = await routingSession.observeNativeChange("Pi thinking-level selection");
|
|
453
|
+
if (result.status !== "ignored") {
|
|
454
|
+
latestCognitiveRoutingContext = ctx;
|
|
455
|
+
providerSurfaceSnapshot = undefined;
|
|
456
|
+
await applyLiveCapabilityStateForSession(ctx);
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
}
|
|
142
460
|
pi.on("resources_discover", async (event, ctx) => {
|
|
143
461
|
const cwd = ctx?.cwd ?? event?.cwd ?? process.cwd();
|
|
144
|
-
const
|
|
462
|
+
const snapshot =
|
|
463
|
+
providerSurfaceSnapshot?.context === ctx
|
|
464
|
+
? providerSurfaceSnapshot.value
|
|
465
|
+
: await buildProviderSurface(ctx ?? { cwd }, false);
|
|
466
|
+
const state = snapshot.capabilityState;
|
|
145
467
|
if (!state.configured) {
|
|
146
468
|
return { skillPaths: [freeflowSkillPath("setup-freeflow")] };
|
|
147
469
|
}
|
|
148
|
-
if (!state.enabled || !
|
|
470
|
+
if (!state.enabled || !hasUsableMandatoryPrompts(snapshot.freeflowContext)) {
|
|
149
471
|
return { skillPaths: [] };
|
|
150
472
|
}
|
|
151
|
-
return { skillPaths: freeflowModelSkillPaths() };
|
|
473
|
+
return { skillPaths: freeflowModelSkillPaths(state) };
|
|
152
474
|
});
|
|
153
|
-
pi.on("session_start", async (
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
475
|
+
pi.on("session_start", async (event, ctx) => {
|
|
476
|
+
routingSession.resetForSession(ctx, event);
|
|
477
|
+
latestCognitiveRoutingContext = ctx;
|
|
478
|
+
providerSurfaceSnapshot = undefined;
|
|
479
|
+
runtimeStateRefreshRequired = true;
|
|
480
|
+
restoreSessionOverrides(ctx);
|
|
481
|
+
freeflowContextRuntime = new FreeflowContextRuntime(ctx);
|
|
482
|
+
contextVirtualizationRuntime = new ContextVirtualizationRuntime(pi, ctx, freeflowContextRuntime);
|
|
483
|
+
conversationHistoryRuntime = new ConversationHistoryRuntime(
|
|
484
|
+
ctx,
|
|
485
|
+
(entryId) => contextVirtualizationRuntime?.isSourceFullyProjected(entryId) ?? true,
|
|
486
|
+
freeflowContextRuntime,
|
|
487
|
+
);
|
|
488
|
+
await contextVirtualizationRuntime.recover(ctx);
|
|
489
|
+
const capabilityState = await readCapabilityState(ctx.cwd, ctx, pi?.host);
|
|
160
490
|
await refreshRuntimeContext(capabilityState);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
491
|
+
routingSession.ensureStartupInactive(ctx, capabilityState.cognitiveRouting?.effective === true);
|
|
492
|
+
routingSession.reconcileNativeEntries(ctx);
|
|
493
|
+
const hasSessionState = sessionHasConversationOrRoutingState(ctx);
|
|
494
|
+
const snapshot = await buildProviderSurface(ctx, hasSessionState);
|
|
495
|
+
if (
|
|
496
|
+
!hasSessionState &&
|
|
497
|
+
snapshot.capabilityState?.cognitiveRouting?.effective === true &&
|
|
498
|
+
routingSession.canAutoActivate()
|
|
499
|
+
) {
|
|
500
|
+
routingSession.armFromCapability(snapshot.capabilityState.cognitiveRouting);
|
|
501
|
+
} else {
|
|
502
|
+
routingSession.clearArmed();
|
|
503
|
+
}
|
|
504
|
+
registerContextToolForState(snapshot.capabilityState);
|
|
505
|
+
const routingSnapshot = routingSession.snapshot();
|
|
506
|
+
setFreeflowStatus(
|
|
507
|
+
ctx,
|
|
508
|
+
snapshot.capabilityState,
|
|
509
|
+
snapshot.cognitiveRoutingRuntime ?? routingSnapshot.runtimeState,
|
|
510
|
+
snapshot.freeflowContext,
|
|
511
|
+
{ startupSelectionSuppressed: routingSnapshot.startupSelectionSuppressed },
|
|
512
|
+
);
|
|
513
|
+
await applyCapabilityToolVisibility(pi, ctx, snapshot.capabilityState, routingSnapshot);
|
|
514
|
+
});
|
|
515
|
+
pi.on("agent_settled", async (_event, ctx) => {
|
|
516
|
+
if (!routingSession.hasController()) return undefined;
|
|
517
|
+
await applyLiveCapabilityStateForSession(ctx);
|
|
518
|
+
return undefined;
|
|
519
|
+
});
|
|
520
|
+
pi.on("session_shutdown", async (event) => {
|
|
521
|
+
await routingSession.shutdown(event?.reason);
|
|
522
|
+
providerSurfaceSnapshot = undefined;
|
|
523
|
+
freeflowContextRuntime = undefined;
|
|
524
|
+
contextVirtualizationRuntime = undefined;
|
|
525
|
+
conversationHistoryRuntime = undefined;
|
|
164
526
|
});
|
|
165
527
|
pi.on("session_tree", async (_event, ctx) => {
|
|
166
|
-
|
|
167
|
-
|
|
528
|
+
latestCognitiveRoutingContext = ctx;
|
|
529
|
+
providerSurfaceSnapshot = undefined;
|
|
530
|
+
runtimeStateRefreshRequired = true;
|
|
531
|
+
restoreSessionOverrides(ctx);
|
|
532
|
+
await routingSession.reconcileBranch();
|
|
533
|
+
if (contextVirtualizationRuntime) {
|
|
534
|
+
contextVirtualizationRuntime.setContext(ctx);
|
|
535
|
+
await contextVirtualizationRuntime.recover(ctx);
|
|
536
|
+
}
|
|
537
|
+
conversationHistoryRuntime?.setContext(ctx);
|
|
538
|
+
await applyLiveCapabilityStateForSession(ctx);
|
|
168
539
|
});
|
|
169
540
|
pi.on("session_compact", async (_event, ctx) => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
541
|
+
latestCognitiveRoutingContext = ctx;
|
|
542
|
+
providerSurfaceSnapshot = undefined;
|
|
543
|
+
runtimeStateRefreshRequired = true;
|
|
544
|
+
await routingSession.reconcileBranch("session-compact");
|
|
545
|
+
if (contextVirtualizationRuntime) {
|
|
546
|
+
contextVirtualizationRuntime.setContext(ctx);
|
|
547
|
+
await contextVirtualizationRuntime.recover(ctx);
|
|
548
|
+
}
|
|
549
|
+
conversationHistoryRuntime?.setContext(ctx);
|
|
550
|
+
await applyLiveCapabilityStateForSession(ctx);
|
|
179
551
|
});
|
|
180
552
|
pi.on("before_agent_start", async (event, ctx) => {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
await applyCapabilityToolVisibility(pi, ctx, capabilityState);
|
|
190
|
-
const freeflowRuntimeContext = runtimeContext(
|
|
191
|
-
const workflowMessage = workflowBootstrapMessage(freeflowContext, capabilityState, ctx.sessionManager);
|
|
553
|
+
latestCognitiveRoutingContext = ctx;
|
|
554
|
+
const snapshot = await buildProviderSurface(ctx, true);
|
|
555
|
+
providerSurfaceSnapshot = { context: ctx, value: snapshot };
|
|
556
|
+
registerContextToolForState(snapshot.capabilityState);
|
|
557
|
+
const routingSnapshot = routingSession.snapshot();
|
|
558
|
+
setFreeflowStatus(ctx, snapshot.capabilityState, snapshot.cognitiveRoutingRuntime, snapshot.freeflowContext, {
|
|
559
|
+
startupSelectionSuppressed: routingSnapshot.startupSelectionSuppressed,
|
|
560
|
+
});
|
|
561
|
+
await applyCapabilityToolVisibility(pi, ctx, snapshot.capabilityState, routingSnapshot);
|
|
562
|
+
const freeflowRuntimeContext = runtimeContext(snapshot.freeflowContext, snapshot.capabilityState);
|
|
192
563
|
const systemPrompt = freeflowRuntimeContext
|
|
193
564
|
? `${event.systemPrompt}\n\n${freeflowRuntimeContext}`
|
|
194
565
|
: event.systemPrompt;
|
|
195
|
-
return {
|
|
566
|
+
return { systemPrompt };
|
|
196
567
|
});
|
|
197
568
|
pi.on("context", async (event, ctx) => {
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
569
|
+
const snapshot =
|
|
570
|
+
providerSurfaceSnapshot?.context === ctx ? providerSurfaceSnapshot.value : await buildProviderSurface(ctx, false);
|
|
571
|
+
if (providerSurfaceSnapshot?.context === ctx) providerSurfaceSnapshot = undefined;
|
|
572
|
+
const cognitiveRoutingRuntime = snapshot.cognitiveRoutingRuntime;
|
|
573
|
+
const surfaceCapabilityState = snapshot.capabilityState;
|
|
574
|
+
let changed = false;
|
|
575
|
+
let messages = event.messages
|
|
576
|
+
.map((message) => {
|
|
577
|
+
const filtered = filterBootstrapMessage(message);
|
|
578
|
+
if (filtered !== message) changed = true;
|
|
579
|
+
return filtered;
|
|
580
|
+
})
|
|
581
|
+
.filter((message) => message !== undefined);
|
|
582
|
+
if (contextVirtualizationRuntime) {
|
|
583
|
+
contextVirtualizationRuntime.setContext(ctx);
|
|
584
|
+
const projected = await contextVirtualizationRuntime.project(
|
|
585
|
+
messages,
|
|
586
|
+
surfaceCapabilityState.contextVirtualization?.effective === true,
|
|
587
|
+
);
|
|
588
|
+
if (projected.changed) {
|
|
589
|
+
changed = true;
|
|
590
|
+
messages = projected.messages;
|
|
591
|
+
}
|
|
201
592
|
}
|
|
202
|
-
|
|
203
|
-
(
|
|
593
|
+
if (conversationHistoryRuntime && surfaceCapabilityState.conversationHistory?.effective === true) {
|
|
594
|
+
conversationHistoryRuntime.setContext(ctx);
|
|
595
|
+
conversationHistoryRuntime.capture(surfaceCapabilityState.contextVirtualization?.effective === true);
|
|
596
|
+
}
|
|
597
|
+
const forceRuntimeStateRefresh = runtimeStateRefreshRequired;
|
|
598
|
+
const nextMessages = withFreeflowRuntimeState(
|
|
599
|
+
messages,
|
|
600
|
+
surfaceCapabilityState,
|
|
601
|
+
cognitiveRoutingRuntime,
|
|
602
|
+
snapshot.freeflowContext,
|
|
603
|
+
{ force: forceRuntimeStateRefresh },
|
|
204
604
|
);
|
|
205
|
-
|
|
605
|
+
if (nextMessages !== messages) {
|
|
606
|
+
changed = true;
|
|
607
|
+
messages = nextMessages;
|
|
608
|
+
}
|
|
609
|
+
if (forceRuntimeStateRefresh) runtimeStateRefreshRequired = false;
|
|
610
|
+
return changed ? { messages } : undefined;
|
|
206
611
|
});
|
|
207
612
|
pi.on("tool_call", async (event, ctx) => {
|
|
208
|
-
const capabilityState = await readCapabilityState(ctx.cwd);
|
|
613
|
+
const capabilityState = await readCapabilityState(ctx.cwd, ctx, pi?.host);
|
|
209
614
|
const toolName = typeof event?.toolName === "string" ? event.toolName : "";
|
|
210
|
-
if (
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
615
|
+
if (
|
|
616
|
+
capabilityState.contextVirtualization?.effective !== true &&
|
|
617
|
+
capabilityState.conversationHistory?.effective !== true &&
|
|
618
|
+
toolName === CONTEXT_VIRTUALIZATION_TOOL_NAME
|
|
619
|
+
) {
|
|
620
|
+
return disabledToolCall(toolName, "context");
|
|
215
621
|
}
|
|
216
622
|
return undefined;
|
|
217
623
|
});
|
|
218
624
|
pi.on("tool_result", async (event, ctx) => {
|
|
219
|
-
const
|
|
220
|
-
if (
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
const observed = await handleObservedToolRouting(event, ctx);
|
|
224
|
-
if (observed) {
|
|
225
|
-
return observed;
|
|
625
|
+
const toolName = typeof event?.toolName === "string" ? event.toolName : "";
|
|
626
|
+
if (routingSession.supportsCognitiveRoutingRuntime() && toolName === COGNITIVE_ROUTING_SWITCH_TOOL_NAME) {
|
|
627
|
+
await applyLiveCapabilityStateForSession(ctx);
|
|
226
628
|
}
|
|
227
|
-
return
|
|
629
|
+
return undefined;
|
|
228
630
|
});
|
|
229
631
|
for (const { command, skill } of WORKFLOW_COMMANDS) {
|
|
230
632
|
pi.registerCommand(command, {
|
|
@@ -245,25 +647,58 @@ export default function freeflow(pi) {
|
|
|
245
647
|
}
|
|
246
648
|
pi.registerCommand("freeflow", {
|
|
247
649
|
description: "Open unified Freeflow settings or print compact status",
|
|
248
|
-
getArgumentCompletions: freeflowCompletions,
|
|
650
|
+
getArgumentCompletions: (prefix) => freeflowCompletions(prefix, routingSession.supportsCognitiveRoutingRuntime()),
|
|
249
651
|
handler: async (args, ctx) => {
|
|
652
|
+
const contextInput = (args ?? "").trim();
|
|
653
|
+
if (contextInput === "context" || contextInput.startsWith("context ")) {
|
|
654
|
+
const capabilityState = await readCapabilityState(ctx.cwd, ctx, pi?.host);
|
|
655
|
+
await handleContextCommand(
|
|
656
|
+
contextInput.slice("context".length).trim(),
|
|
657
|
+
ctx,
|
|
658
|
+
contextVirtualizationRuntime,
|
|
659
|
+
capabilityState.contextVirtualization?.effective === true,
|
|
660
|
+
capabilityState.conversationHistory?.effective === true,
|
|
661
|
+
);
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
if (routingSession.supportsCognitiveRoutingRuntime() && /^profile(?:\s|$)/i.test((args ?? "").trim())) {
|
|
665
|
+
const profileCommandContext = {
|
|
666
|
+
isIdle: ctx?.isIdle,
|
|
667
|
+
ui: ctx?.ui,
|
|
668
|
+
history: (options) => routingSession.history(options) ?? readCognitiveRoutingHistory(ctx, options),
|
|
669
|
+
};
|
|
670
|
+
const historyCommand = /^profile\s+history(?:\s|$)/i.test((args ?? "").trim());
|
|
671
|
+
if (historyCommand) {
|
|
672
|
+
await handleCognitiveRoutingProfileCommand(args, profileCommandContext, routingSession.commandController());
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
if (!routingSession.hasController() && !routingSession.armed) {
|
|
676
|
+
routingSession.beginExplicitReactivation();
|
|
677
|
+
await applyLiveCapabilityStateForSession(ctx, { reconcileCognitiveRouting: true });
|
|
678
|
+
}
|
|
679
|
+
const profileController = routingSession.commandController();
|
|
680
|
+
if (await handleCognitiveRoutingProfileCommand(args, profileCommandContext, profileController)) {
|
|
681
|
+
if (profileController) {
|
|
682
|
+
routingSession.beginExplicitReactivation();
|
|
683
|
+
await applyLiveCapabilityStateForSession(ctx, {
|
|
684
|
+
reconcileCognitiveRouting: routingSession.armed !== undefined,
|
|
685
|
+
materializeCognitiveRouting: routingSession.armed !== undefined && !isPiFlowHost(pi?.host),
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
250
691
|
await handleFreeflowCommand(
|
|
251
692
|
args,
|
|
252
693
|
ctx,
|
|
253
|
-
async () => {
|
|
254
|
-
await
|
|
694
|
+
async (_changed, options = {}) => {
|
|
695
|
+
await applyLiveCapabilityStateForSession(ctx, {
|
|
696
|
+
reconcileCognitiveRouting: options.reconcileCognitiveRouting ?? true,
|
|
697
|
+
});
|
|
255
698
|
},
|
|
256
699
|
pi,
|
|
700
|
+
routingSession.commandController(),
|
|
257
701
|
);
|
|
258
702
|
},
|
|
259
703
|
});
|
|
260
|
-
pi.registerCommand("output-router", {
|
|
261
|
-
description: "Open Freeflow Output Router settings or print compact status",
|
|
262
|
-
getArgumentCompletions: capabilityCompletions,
|
|
263
|
-
handler: async (args, ctx) => {
|
|
264
|
-
await handleOutputRouterCommand(args, ctx, async () => {
|
|
265
|
-
await applyLiveCapabilityState(pi, ctx);
|
|
266
|
-
});
|
|
267
|
-
},
|
|
268
|
-
});
|
|
269
704
|
}
|