pal-code 0.1.0__tar.gz
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.
- pal_code-0.1.0/LICENSE +21 -0
- pal_code-0.1.0/PKG-INFO +379 -0
- pal_code-0.1.0/README.md +322 -0
- pal_code-0.1.0/pyproject.toml +93 -0
- pal_code-0.1.0/setup.cfg +4 -0
- pal_code-0.1.0/src/pal/__init__.py +29 -0
- pal_code-0.1.0/src/pal/__main__.py +3 -0
- pal_code-0.1.0/src/pal/access_manager/__init__.py +16 -0
- pal_code-0.1.0/src/pal/access_manager/components/__init__.py +14 -0
- pal_code-0.1.0/src/pal/access_manager/components/access_control.py +41 -0
- pal_code-0.1.0/src/pal/access_manager/components/base.py +39 -0
- pal_code-0.1.0/src/pal/access_manager/components/intervention.py +31 -0
- pal_code-0.1.0/src/pal/access_manager/components/privilege_registry.py +30 -0
- pal_code-0.1.0/src/pal/access_manager/pipeline.py +68 -0
- pal_code-0.1.0/src/pal/access_manager/utils/__init__.py +2 -0
- pal_code-0.1.0/src/pal/agent_constraints/__init__.py +3 -0
- pal_code-0.1.0/src/pal/agent_constraints/components/AGENT_OUTPUT.md +13 -0
- pal_code-0.1.0/src/pal/agent_constraints/components/__init__.py +3 -0
- pal_code-0.1.0/src/pal/agent_constraints/components/constraints.py +22 -0
- pal_code-0.1.0/src/pal/agent_constraints/pipeline.py +22 -0
- pal_code-0.1.0/src/pal/agent_constraints/utils/__init__.py +2 -0
- pal_code-0.1.0/src/pal/agents/__init__.py +12 -0
- pal_code-0.1.0/src/pal/agents/coding.py +14 -0
- pal_code-0.1.0/src/pal/agents/docs.py +15 -0
- pal_code-0.1.0/src/pal/chat/__init__.py +4 -0
- pal_code-0.1.0/src/pal/chat/demo.py +231 -0
- pal_code-0.1.0/src/pal/chat/providers.py +23 -0
- pal_code-0.1.0/src/pal/chat/service.py +591 -0
- pal_code-0.1.0/src/pal/chat/services/__init__.py +26 -0
- pal_code-0.1.0/src/pal/chat/services/base.py +142 -0
- pal_code-0.1.0/src/pal/chat/services/data.py +142 -0
- pal_code-0.1.0/src/pal/chat/services/media.py +123 -0
- pal_code-0.1.0/src/pal/chat/services/web.py +60 -0
- pal_code-0.1.0/src/pal/chat/sessions.py +108 -0
- pal_code-0.1.0/src/pal/chat/tools.py +446 -0
- pal_code-0.1.0/src/pal/chat/uploads.py +81 -0
- pal_code-0.1.0/src/pal/cli.py +502 -0
- pal_code-0.1.0/src/pal/compression/__init__.py +12 -0
- pal_code-0.1.0/src/pal/compression/components/__init__.py +64 -0
- pal_code-0.1.0/src/pal/compression/components/adverbs.py +20 -0
- pal_code-0.1.0/src/pal/compression/components/hedges.py +54 -0
- pal_code-0.1.0/src/pal/compression/components/interjections.py +20 -0
- pal_code-0.1.0/src/pal/compression/components/minifier.py +56 -0
- pal_code-0.1.0/src/pal/compression/components/output_compressor.py +13 -0
- pal_code-0.1.0/src/pal/compression/components/pleonasms.py +54 -0
- pal_code-0.1.0/src/pal/compression/components/punctuations.py +36 -0
- pal_code-0.1.0/src/pal/compression/components/stopwords.py +62 -0
- pal_code-0.1.0/src/pal/compression/history.py +346 -0
- pal_code-0.1.0/src/pal/compression/pipeline.py +58 -0
- pal_code-0.1.0/src/pal/compression/utils/__init__.py +30 -0
- pal_code-0.1.0/src/pal/compression/utils/negations.py +18 -0
- pal_code-0.1.0/src/pal/compression/utils/nltk_setup.py +20 -0
- pal_code-0.1.0/src/pal/compression/utils/pronouns.py +27 -0
- pal_code-0.1.0/src/pal/compression/utils/proselint_setup.py +9 -0
- pal_code-0.1.0/src/pal/compression/utils/spacy_setup.py +22 -0
- pal_code-0.1.0/src/pal/config/default.yaml +163 -0
- pal_code-0.1.0/src/pal/config.py +504 -0
- pal_code-0.1.0/src/pal/context_manager/__init__.py +7 -0
- pal_code-0.1.0/src/pal/context_manager/chat_context.py +117 -0
- pal_code-0.1.0/src/pal/context_manager/components/__init__.py +5 -0
- pal_code-0.1.0/src/pal/context_manager/components/assembler.py +75 -0
- pal_code-0.1.0/src/pal/context_manager/components/context_cache.py +45 -0
- pal_code-0.1.0/src/pal/context_manager/components/kv_bridge.py +16 -0
- pal_code-0.1.0/src/pal/context_manager/components/pager.py +48 -0
- pal_code-0.1.0/src/pal/context_manager/components/simple_context_manager.py +56 -0
- pal_code-0.1.0/src/pal/context_manager/components/turns.py +88 -0
- pal_code-0.1.0/src/pal/context_manager/pipeline.py +27 -0
- pal_code-0.1.0/src/pal/context_manager/utils/__init__.py +18 -0
- pal_code-0.1.0/src/pal/context_manager/utils/hashing.py +5 -0
- pal_code-0.1.0/src/pal/context_manager/utils/relevance.py +59 -0
- pal_code-0.1.0/src/pal/context_manager/utils/storage.py +37 -0
- pal_code-0.1.0/src/pal/documents/__init__.py +4 -0
- pal_code-0.1.0/src/pal/documents/components/__init__.py +0 -0
- pal_code-0.1.0/src/pal/documents/components/chunker.py +79 -0
- pal_code-0.1.0/src/pal/documents/components/index.py +155 -0
- pal_code-0.1.0/src/pal/documents/utils/__init__.py +1 -0
- pal_code-0.1.0/src/pal/errors.py +40 -0
- pal_code-0.1.0/src/pal/input_converters/__init__.py +8 -0
- pal_code-0.1.0/src/pal/input_converters/components/__init__.py +0 -0
- pal_code-0.1.0/src/pal/input_converters/components/base.py +38 -0
- pal_code-0.1.0/src/pal/input_converters/components/pandoc_converter.py +87 -0
- pal_code-0.1.0/src/pal/input_converters/components/pdf_converter.py +46 -0
- pal_code-0.1.0/src/pal/input_converters/components/pptx_converter.py +52 -0
- pal_code-0.1.0/src/pal/input_converters/components/xlsx_converter.py +38 -0
- pal_code-0.1.0/src/pal/input_converters/pipeline.py +72 -0
- pal_code-0.1.0/src/pal/input_converters/utils/__init__.py +1 -0
- pal_code-0.1.0/src/pal/input_converters/workspace.py +56 -0
- pal_code-0.1.0/src/pal/input_savers/INPUT_RULES.md +2 -0
- pal_code-0.1.0/src/pal/input_savers/__init__.py +5 -0
- pal_code-0.1.0/src/pal/input_savers/components/__init__.py +0 -0
- pal_code-0.1.0/src/pal/input_savers/components/base.py +40 -0
- pal_code-0.1.0/src/pal/input_savers/components/methods.py +41 -0
- pal_code-0.1.0/src/pal/input_savers/components/verifier.py +39 -0
- pal_code-0.1.0/src/pal/input_savers/pipeline.py +154 -0
- pal_code-0.1.0/src/pal/input_savers/utils/__init__.py +0 -0
- pal_code-0.1.0/src/pal/input_savers/utils/guards.py +94 -0
- pal_code-0.1.0/src/pal/knowledge_graph/__init__.py +10 -0
- pal_code-0.1.0/src/pal/knowledge_graph/components/__init__.py +0 -0
- pal_code-0.1.0/src/pal/knowledge_graph/components/base.py +50 -0
- pal_code-0.1.0/src/pal/knowledge_graph/components/builder.py +54 -0
- pal_code-0.1.0/src/pal/knowledge_graph/components/retriever.py +100 -0
- pal_code-0.1.0/src/pal/knowledge_graph/components/workspace.py +116 -0
- pal_code-0.1.0/src/pal/knowledge_graph/pipeline.py +215 -0
- pal_code-0.1.0/src/pal/knowledge_graph/utils/__init__.py +1 -0
- pal_code-0.1.0/src/pal/latency_tracker/__init__.py +3 -0
- pal_code-0.1.0/src/pal/latency_tracker/pipeline.py +86 -0
- pal_code-0.1.0/src/pal/llm_scheduler/__init__.py +11 -0
- pal_code-0.1.0/src/pal/llm_scheduler/api.py +137 -0
- pal_code-0.1.0/src/pal/llm_scheduler/code.py +28 -0
- pal_code-0.1.0/src/pal/llm_scheduler/core.py +92 -0
- pal_code-0.1.0/src/pal/llm_scheduler/local.py +215 -0
- pal_code-0.1.0/src/pal/llm_scheduler/pipeline.py +42 -0
- pal_code-0.1.0/src/pal/llm_scheduler/types.py +92 -0
- pal_code-0.1.0/src/pal/llm_wrapper/__init__.py +34 -0
- pal_code-0.1.0/src/pal/llm_wrapper/adapter.py +316 -0
- pal_code-0.1.0/src/pal/llm_wrapper/components/__init__.py +23 -0
- pal_code-0.1.0/src/pal/llm_wrapper/components/adapter_types.py +90 -0
- pal_code-0.1.0/src/pal/llm_wrapper/components/base.py +195 -0
- pal_code-0.1.0/src/pal/llm_wrapper/components/features.py +104 -0
- pal_code-0.1.0/src/pal/llm_wrapper/components/litellm_wrapper.py +215 -0
- pal_code-0.1.0/src/pal/llm_wrapper/components/openrouter_wrapper.py +114 -0
- pal_code-0.1.0/src/pal/llm_wrapper/modes.py +73 -0
- pal_code-0.1.0/src/pal/llm_wrapper/pipeline.py +61 -0
- pal_code-0.1.0/src/pal/llm_wrapper/utils/__init__.py +4 -0
- pal_code-0.1.0/src/pal/llm_wrapper/utils/registry.py +49 -0
- pal_code-0.1.0/src/pal/llm_wrapper/utils/token_counting.py +10 -0
- pal_code-0.1.0/src/pal/local_llm/__init__.py +5 -0
- pal_code-0.1.0/src/pal/local_llm/components/__init__.py +0 -0
- pal_code-0.1.0/src/pal/local_llm/components/huggingface_local.py +217 -0
- pal_code-0.1.0/src/pal/local_llm/components/local_llm.py +60 -0
- pal_code-0.1.0/src/pal/logging_setup.py +18 -0
- pal_code-0.1.0/src/pal/memory/__init__.py +7 -0
- pal_code-0.1.0/src/pal/memory/components/__init__.py +6 -0
- pal_code-0.1.0/src/pal/memory/components/lru_k.py +56 -0
- pal_code-0.1.0/src/pal/memory/components/manager.py +98 -0
- pal_code-0.1.0/src/pal/memory/components/note.py +54 -0
- pal_code-0.1.0/src/pal/memory/components/storage_manager.py +60 -0
- pal_code-0.1.0/src/pal/memory/pipeline.py +122 -0
- pal_code-0.1.0/src/pal/memory/utils/__init__.py +3 -0
- pal_code-0.1.0/src/pal/memory/utils/keyword_overlap.py +3 -0
- pal_code-0.1.0/src/pal/memory_tracker/__init__.py +3 -0
- pal_code-0.1.0/src/pal/memory_tracker/components/__init__.py +0 -0
- pal_code-0.1.0/src/pal/memory_tracker/components/process.py +56 -0
- pal_code-0.1.0/src/pal/memory_tracker/pipeline.py +44 -0
- pal_code-0.1.0/src/pal/metrics/__init__.py +4 -0
- pal_code-0.1.0/src/pal/metrics/components/__init__.py +4 -0
- pal_code-0.1.0/src/pal/metrics/components/collector.py +140 -0
- pal_code-0.1.0/src/pal/metrics/components/exporter.py +28 -0
- pal_code-0.1.0/src/pal/metrics/pipeline.py +49 -0
- pal_code-0.1.0/src/pal/metrics/utils/__init__.py +2 -0
- pal_code-0.1.0/src/pal/notes_manager/__init__.py +5 -0
- pal_code-0.1.0/src/pal/notes_manager/components/__init__.py +0 -0
- pal_code-0.1.0/src/pal/notes_manager/components/privacy.py +14 -0
- pal_code-0.1.0/src/pal/notes_manager/components/recall.py +31 -0
- pal_code-0.1.0/src/pal/notes_manager/components/tidy.py +28 -0
- pal_code-0.1.0/src/pal/notes_manager/pipeline.py +138 -0
- pal_code-0.1.0/src/pal/orchestrator/__init__.py +26 -0
- pal_code-0.1.0/src/pal/orchestrator/components/__init__.py +26 -0
- pal_code-0.1.0/src/pal/orchestrator/components/agent.py +105 -0
- pal_code-0.1.0/src/pal/orchestrator/components/cgroup_manager.py +209 -0
- pal_code-0.1.0/src/pal/orchestrator/components/context_interrupt.py +220 -0
- pal_code-0.1.0/src/pal/orchestrator/components/limits.py +9 -0
- pal_code-0.1.0/src/pal/orchestrator/components/scheduler.py +69 -0
- pal_code-0.1.0/src/pal/orchestrator/components/syscall_scheduler.py +200 -0
- pal_code-0.1.0/src/pal/orchestrator/pipeline.py +228 -0
- pal_code-0.1.0/src/pal/orchestrator/utils/__init__.py +4 -0
- pal_code-0.1.0/src/pal/orchestrator/utils/device.py +164 -0
- pal_code-0.1.0/src/pal/orchestrator/utils/protocol.py +32 -0
- pal_code-0.1.0/src/pal/os_kernel/__init__.py +5 -0
- pal_code-0.1.0/src/pal/os_kernel/filesystem.py +80 -0
- pal_code-0.1.0/src/pal/os_kernel/network.py +146 -0
- pal_code-0.1.0/src/pal/os_kernel/pipeline.py +175 -0
- pal_code-0.1.0/src/pal/os_kernel/sysinfo.py +36 -0
- pal_code-0.1.0/src/pal/paths.py +59 -0
- pal_code-0.1.0/src/pal/pipeline.py +177 -0
- pal_code-0.1.0/src/pal/py.typed +0 -0
- pal_code-0.1.0/src/pal/redact.py +19 -0
- pal_code-0.1.0/src/pal/sdk/__init__.py +33 -0
- pal_code-0.1.0/src/pal/sdk/adapters.py +43 -0
- pal_code-0.1.0/src/pal/sdk/agent.py +99 -0
- pal_code-0.1.0/src/pal/sdk/components/__init__.py +14 -0
- pal_code-0.1.0/src/pal/sdk/components/autogen_adapter.py +65 -0
- pal_code-0.1.0/src/pal/sdk/components/autogen_client.py +98 -0
- pal_code-0.1.0/src/pal/sdk/components/framework_adapter_base.py +69 -0
- pal_code-0.1.0/src/pal/sdk/components/metagpt_adapter.py +46 -0
- pal_code-0.1.0/src/pal/sdk/components/open_interpreter_adapter.py +47 -0
- pal_code-0.1.0/src/pal/sdk/components/tool_catalog.py +44 -0
- pal_code-0.1.0/src/pal/sdk/os_api.py +84 -0
- pal_code-0.1.0/src/pal/sdk/patterns.py +129 -0
- pal_code-0.1.0/src/pal/sdk/pipeline.py +240 -0
- pal_code-0.1.0/src/pal/sdk/queries.py +68 -0
- pal_code-0.1.0/src/pal/sdk/savers.py +88 -0
- pal_code-0.1.0/src/pal/sdk/utils/__init__.py +2 -0
- pal_code-0.1.0/src/pal/storage_manager/__init__.py +17 -0
- pal_code-0.1.0/src/pal/storage_manager/components/__init__.py +19 -0
- pal_code-0.1.0/src/pal/storage_manager/components/base.py +50 -0
- pal_code-0.1.0/src/pal/storage_manager/components/local_file_backend.py +84 -0
- pal_code-0.1.0/src/pal/storage_manager/components/storage_queue.py +91 -0
- pal_code-0.1.0/src/pal/storage_manager/components/vector_store_backend.py +122 -0
- pal_code-0.1.0/src/pal/storage_manager/pipeline.py +153 -0
- pal_code-0.1.0/src/pal/storage_manager/utils/__init__.py +4 -0
- pal_code-0.1.0/src/pal/storage_manager/utils/memory_adapter.py +60 -0
- pal_code-0.1.0/src/pal/storage_manager/utils/sdk.py +93 -0
- pal_code-0.1.0/src/pal/studio/__init__.py +0 -0
- pal_code-0.1.0/src/pal/studio/builder.py +166 -0
- pal_code-0.1.0/src/pal/studio/catalog.py +90 -0
- pal_code-0.1.0/src/pal/studio/checks.py +129 -0
- pal_code-0.1.0/src/pal/studio/clients.py +6 -0
- pal_code-0.1.0/src/pal/studio/editor.py +137 -0
- pal_code-0.1.0/src/pal/studio/files.py +6 -0
- pal_code-0.1.0/src/pal/studio/models.py +6 -0
- pal_code-0.1.0/src/pal/studio/plan.py +149 -0
- pal_code-0.1.0/src/pal/studio/planner.py +205 -0
- pal_code-0.1.0/src/pal/studio/policy.py +69 -0
- pal_code-0.1.0/src/pal/studio/routes.py +254 -0
- pal_code-0.1.0/src/pal/studio/runs.py +210 -0
- pal_code-0.1.0/src/pal/task_router/__init__.py +11 -0
- pal_code-0.1.0/src/pal/task_router/components/__init__.py +0 -0
- pal_code-0.1.0/src/pal/task_router/components/answerer.py +37 -0
- pal_code-0.1.0/src/pal/task_router/components/base.py +34 -0
- pal_code-0.1.0/src/pal/task_router/components/classifier.py +40 -0
- pal_code-0.1.0/src/pal/task_router/components/gates.py +23 -0
- pal_code-0.1.0/src/pal/task_router/pipeline.py +61 -0
- pal_code-0.1.0/src/pal/task_router/utils/__init__.py +1 -0
- pal_code-0.1.0/src/pal/terminal/__init__.py +1 -0
- pal_code-0.1.0/src/pal/terminal/backend.py +141 -0
- pal_code-0.1.0/src/pal/terminal/bench.py +173 -0
- pal_code-0.1.0/src/pal/terminal/cli.py +826 -0
- pal_code-0.1.0/src/pal/terminal/clients.py +170 -0
- pal_code-0.1.0/src/pal/terminal/commands.py +401 -0
- pal_code-0.1.0/src/pal/terminal/decide.py +242 -0
- pal_code-0.1.0/src/pal/terminal/files.py +55 -0
- pal_code-0.1.0/src/pal/terminal/flow_cli.py +439 -0
- pal_code-0.1.0/src/pal/terminal/hardware.py +199 -0
- pal_code-0.1.0/src/pal/terminal/history.py +88 -0
- pal_code-0.1.0/src/pal/terminal/keys.py +83 -0
- pal_code-0.1.0/src/pal/terminal/local_models.py +261 -0
- pal_code-0.1.0/src/pal/terminal/logo.py +117 -0
- pal_code-0.1.0/src/pal/terminal/models.py +99 -0
- pal_code-0.1.0/src/pal/terminal/policy.py +54 -0
- pal_code-0.1.0/src/pal/terminal/project.py +413 -0
- pal_code-0.1.0/src/pal/terminal/review.py +65 -0
- pal_code-0.1.0/src/pal/terminal/security.py +239 -0
- pal_code-0.1.0/src/pal/terminal/session.py +503 -0
- pal_code-0.1.0/src/pal/terminal/setup.py +354 -0
- pal_code-0.1.0/src/pal/terminal/syntax.py +98 -0
- pal_code-0.1.0/src/pal/terminal/theme.py +37 -0
- pal_code-0.1.0/src/pal/terminal/ui.py +647 -0
- pal_code-0.1.0/src/pal/terminal/voice.py +137 -0
- pal_code-0.1.0/src/pal/terminal/workflow.py +624 -0
- pal_code-0.1.0/src/pal/token_tracker/__init__.py +3 -0
- pal_code-0.1.0/src/pal/token_tracker/pipeline.py +54 -0
- pal_code-0.1.0/src/pal/tokens.py +21 -0
- pal_code-0.1.0/src/pal/tool_catalog.py +107 -0
- pal_code-0.1.0/src/pal/tool_manager/__init__.py +17 -0
- pal_code-0.1.0/src/pal/tool_manager/builtin.py +82 -0
- pal_code-0.1.0/src/pal/tool_manager/components/__init__.py +19 -0
- pal_code-0.1.0/src/pal/tool_manager/components/base.py +53 -0
- pal_code-0.1.0/src/pal/tool_manager/components/conflict_resolver.py +27 -0
- pal_code-0.1.0/src/pal/tool_manager/components/param_validator.py +41 -0
- pal_code-0.1.0/src/pal/tool_manager/components/tool_call_queue.py +111 -0
- pal_code-0.1.0/src/pal/tool_manager/components/tool_registry.py +60 -0
- pal_code-0.1.0/src/pal/tool_manager/pipeline.py +80 -0
- pal_code-0.1.0/src/pal/tool_manager/utils/__init__.py +3 -0
- pal_code-0.1.0/src/pal/web/__init__.py +3 -0
- pal_code-0.1.0/src/pal/web/app.py +276 -0
- pal_code-0.1.0/src/pal/web/static/editor.js +219 -0
- pal_code-0.1.0/src/pal/web/static/fonts/LICENSE-Inter.txt +3 -0
- pal_code-0.1.0/src/pal/web/static/fonts/inter-400.woff2 +0 -0
- pal_code-0.1.0/src/pal/web/static/fonts/inter-500.woff2 +0 -0
- pal_code-0.1.0/src/pal/web/static/fonts/inter-600.woff2 +0 -0
- pal_code-0.1.0/src/pal/web/static/fonts/inter-700.woff2 +0 -0
- pal_code-0.1.0/src/pal/web/static/inter.css +5 -0
- pal_code-0.1.0/src/pal/web/static/pal-logo-256.png +0 -0
- pal_code-0.1.0/src/pal/web/static/pal-logo-32.png +0 -0
- pal_code-0.1.0/src/pal/web/static/pal-logo-64.png +0 -0
- pal_code-0.1.0/src/pal/web/static/studio.css +306 -0
- pal_code-0.1.0/src/pal/web/static/studio.js +533 -0
- pal_code-0.1.0/src/pal/web/static/voice.js +76 -0
- pal_code-0.1.0/src/pal/web/templates/index.html +368 -0
- pal_code-0.1.0/src/pal/web/templates/studio.html +120 -0
- pal_code-0.1.0/src/pal_code.egg-info/PKG-INFO +379 -0
- pal_code-0.1.0/src/pal_code.egg-info/SOURCES.txt +292 -0
- pal_code-0.1.0/src/pal_code.egg-info/dependency_links.txt +1 -0
- pal_code-0.1.0/src/pal_code.egg-info/entry_points.txt +2 -0
- pal_code-0.1.0/src/pal_code.egg-info/requires.txt +48 -0
- pal_code-0.1.0/src/pal_code.egg-info/top_level.txt +1 -0
- pal_code-0.1.0/tests/test_cli.py +357 -0
- pal_code-0.1.0/tests/test_config.py +115 -0
- pal_code-0.1.0/tests/test_lockfile.py +30 -0
- pal_code-0.1.0/tests/test_paths.py +37 -0
- pal_code-0.1.0/tests/test_redact.py +28 -0
- pal_code-0.1.0/tests/test_run_script.py +91 -0
- pal_code-0.1.0/tests/test_tool_catalog.py +85 -0
pal_code-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nandini Singh
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
pal_code-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pal-code
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Pal: build and plan with AI in your terminal (pal cli) or browser (pal web), on a layer that cuts tokens and latency.
|
|
5
|
+
Author: Nandini Singh
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: ai,coding-assistant,cli,llm,ollama,tokens,code-graph
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Software Development
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: requests>=2.31
|
|
19
|
+
Requires-Dist: pyyaml>=6.0
|
|
20
|
+
Requires-Dist: flask>=3.0
|
|
21
|
+
Requires-Dist: waitress>=3.0
|
|
22
|
+
Requires-Dist: rich>=13.7
|
|
23
|
+
Requires-Dist: prompt_toolkit>=3.0.43
|
|
24
|
+
Requires-Dist: litellm==1.102.1
|
|
25
|
+
Requires-Dist: graphifyy>=0.9
|
|
26
|
+
Requires-Dist: pypdf>=4.0
|
|
27
|
+
Requires-Dist: python-pptx>=0.6.23
|
|
28
|
+
Requires-Dist: openpyxl>=3.1
|
|
29
|
+
Provides-Extra: documents
|
|
30
|
+
Requires-Dist: pymupdf4llm>=0.0.17; extra == "documents"
|
|
31
|
+
Provides-Extra: graph
|
|
32
|
+
Provides-Extra: compression
|
|
33
|
+
Requires-Dist: nltk; extra == "compression"
|
|
34
|
+
Requires-Dist: spacy; extra == "compression"
|
|
35
|
+
Requires-Dist: proselint; extra == "compression"
|
|
36
|
+
Provides-Extra: litellm
|
|
37
|
+
Provides-Extra: vector
|
|
38
|
+
Requires-Dist: chromadb; extra == "vector"
|
|
39
|
+
Provides-Extra: embeddings
|
|
40
|
+
Requires-Dist: sentence-transformers; extra == "embeddings"
|
|
41
|
+
Provides-Extra: inprocess
|
|
42
|
+
Requires-Dist: torch; extra == "inprocess"
|
|
43
|
+
Requires-Dist: transformers; extra == "inprocess"
|
|
44
|
+
Provides-Extra: voice
|
|
45
|
+
Requires-Dist: sounddevice>=0.4; extra == "voice"
|
|
46
|
+
Requires-Dist: numpy>=1.24; extra == "voice"
|
|
47
|
+
Requires-Dist: faster-whisper>=1.0; extra == "voice"
|
|
48
|
+
Provides-Extra: full
|
|
49
|
+
Requires-Dist: pal-code[documents,voice]; extra == "full"
|
|
50
|
+
Provides-Extra: dev
|
|
51
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
52
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
53
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
54
|
+
Requires-Dist: types-requests; extra == "dev"
|
|
55
|
+
Requires-Dist: types-PyYAML; extra == "dev"
|
|
56
|
+
Dynamic: license-file
|
|
57
|
+
|
|
58
|
+
# Pal
|
|
59
|
+
|
|
60
|
+
Build and plan with AI, in your terminal or your browser, with fewer tokens. Three built-in agents: **Ask**, **Build** and **Plan**.
|
|
61
|
+
Underneath is the Pal layer, which cuts tokens and latency: only the relevant history and files are sent, a file the model already has is not
|
|
62
|
+
sent again, and long conversations are paged and compressed.
|
|
63
|
+
|
|
64
|
+
Works with a local model (Ollama) or an API model: Anthropic, OpenAI, Gemini, Groq, DeepSeek, Mistral, Together or OpenRouter.
|
|
65
|
+
|
|
66
|
+
## Quick start
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install pal-code # 1. install
|
|
70
|
+
|
|
71
|
+
cd my-project
|
|
72
|
+
pal cli # 2. the terminal: the session opens and works in this folder
|
|
73
|
+
|
|
74
|
+
pal web # 3. or the browser: opens Pal in your default browser
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`pal web` runs a small server on this computer only (`http://127.0.0.1:5000`) and opens the Studio, with the chat and the code editor one click
|
|
78
|
+
away. Press Ctrl+C in the terminal to stop it. Options: `pal web --port 8080`, `pal web --page chat`, `pal web --no-open`, `pal web --dir <folder>`.
|
|
79
|
+
|
|
80
|
+
### What `pal cli` and `pal web` set up, every time they start
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
✓ Local LLM Ollama running · qwen2.5-coder:7b · helper qwen2.5:1.5b
|
|
84
|
+
✓ Project map 214 files, 2.1k tokens (the code itself is about 180k)
|
|
85
|
+
… Code graph built in the background; the session can start now
|
|
86
|
+
✓ Documents 3 converted to markdown, 2 text files indexed: only matching passages are sent
|
|
87
|
+
docs/spec.pdf → ~/.pal/projects/shop-1a2b3c/markdown/docs/spec.pdf.md
|
|
88
|
+
✓ Tests python -m pytest -q
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- **Local LLM:** on a computer with a GPU, Pal makes sure local models can run. If Ollama is missing it offers to install it (asks first),
|
|
92
|
+
starts it if it is not running, and offers to download the models chosen for your GPU when they are missing. No GPU: API models only.
|
|
93
|
+
- **Project map:** every source file with its classes and functions, in a few thousand tokens. It is indexed, so a question about
|
|
94
|
+
"the login handler" brings the lines of the map that name it, not the project.
|
|
95
|
+
- **Code graph:** built with graphify from your code (AST only: no model, nothing leaves the computer). Each request gets the graph nodes and
|
|
96
|
+
code excerpts that match it.
|
|
97
|
+
- **Documents:** PDF, Word, PowerPoint, Excel, EPUB, RTF and LaTeX files are converted to markdown files (in `~/.pal/projects/...`, never in
|
|
98
|
+
your folder) and indexed with your markdown and text files. Word files work without pandoc.
|
|
99
|
+
- Only what changed is redone the next time (a second start takes well under a second). `/project` shows it again; `/project rebuild` reads
|
|
100
|
+
the folder again. A `.palignore` file (like `.gitignore`) leaves folders or files out.
|
|
101
|
+
|
|
102
|
+
**First run sets up Pal for your computer.** The first `pal cli` or `pal web` looks at your GPU (NVIDIA, AMD, Apple Silicon) and asks
|
|
103
|
+
which **main model** (it writes and plans) you want:
|
|
104
|
+
- **A local model:** Pal shows the models that suit your GPU, the best first (installed ones marked), and downloads the one you pick.
|
|
105
|
+
You can also type any Ollama model name.
|
|
106
|
+
- **An API model** (OpenAI, Anthropic, Gemini, OpenRouter, any LiteLLM model or your own endpoint): nothing big to download. The key is asked
|
|
107
|
+
for when needed and never saved.
|
|
108
|
+
|
|
109
|
+
Either way Pal downloads the **helper**, a small fast local model for its own jobs on every request (routing, trimming what you type,
|
|
110
|
+
checking answers). Change the main model any time with `/model`: the same list, and picking a model that is not installed downloads it.
|
|
111
|
+
|
|
112
|
+
| Your GPU | Main model | Helper |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| none | API models only | none |
|
|
115
|
+
| 4 GB | qwen2.5-coder:3b | qwen2.5:0.5b |
|
|
116
|
+
| 8 GB | qwen2.5-coder:7b | qwen2.5:1.5b |
|
|
117
|
+
| 12 GB | qwen2.5-coder:14b | qwen2.5:1.5b |
|
|
118
|
+
| 16 GB | qwen2.5-coder:14b | llama3.2:3b |
|
|
119
|
+
| 20 GB | devstral-small-2:24b | llama3.2:3b |
|
|
120
|
+
| 24 GB and more | qwen3-coder:30b | llama3.2:3b |
|
|
121
|
+
| Mac, 16 GB | qwen2.5-coder:14b | qwen2.5:1.5b |
|
|
122
|
+
| Mac, 32 GB and more | qwen3-coder:30b | llama3.2:3b |
|
|
123
|
+
|
|
124
|
+
The catalogue (`pal setup --list`) also has the newer thinking models (qwen3.5, qwen3.6, gemma4, gpt-oss): they reason before answering,
|
|
125
|
+
so Pal lists them but does not pick them by itself. Choose one with `/model qwen3.6:27b`.
|
|
126
|
+
|
|
127
|
+
**No GPU? API models only.** On a computer without a GPU Pal offers no local model: it asks for an API provider, a model and a key (the key is used for
|
|
128
|
+
that session and never saved), and Pal's local helper jobs (routing, trimming what you type, checking answers) are off, so your message goes to the
|
|
129
|
+
API model as typed. The savers that need no model still work: only the relevant history, files and code are sent, and files are not sent twice.
|
|
130
|
+
|
|
131
|
+
`pal setup` runs it again, `pal setup --list` shows all 39 models grouped by the GPU memory they need with how each fits your computer, and
|
|
132
|
+
`pal setup --hardware gpu:24` shows what another computer would get. Sizes are Ollama's 4-bit downloads (approximate). Ollama itself comes from
|
|
133
|
+
https://ollama.com/download.
|
|
134
|
+
|
|
135
|
+
**API models instead:** `/key openrouter <key>` in a session (kept for that session only, never saved), then `/model openrouter:<name>`, or set
|
|
136
|
+
`OPENROUTER_API_KEY` (or OPENAI, ANTHROPIC, GEMINI ...) and run `pal cli --provider openrouter --model <name>`. The helper still runs locally.
|
|
137
|
+
|
|
138
|
+
**Files:** `@notes.md` adds a file from your folder; `/add <file>` attaches one from anywhere, and dropping files on the terminal window does the same.
|
|
139
|
+
Text and code files go as they are; PDF, Word, PowerPoint, Excel and HTML are converted to text first. The web interface has a + button.
|
|
140
|
+
|
|
141
|
+
From a source checkout, `python run.py` (Windows: `py run.py`) creates `.venv`, installs everything the first time and opens the web interface;
|
|
142
|
+
`python run.py cli` opens the terminal session.
|
|
143
|
+
|
|
144
|
+
`pal doctor` checks the machine.
|
|
145
|
+
|
|
146
|
+
### Agents and the SDK
|
|
147
|
+
|
|
148
|
+
The **agent application layer** holds agents only. Two native agents ship, both on Gemini and both using the full
|
|
149
|
+
token-saving pipeline: a coding agent and a documentation agent. Put their keys in `.env`
|
|
150
|
+
(`GEMINI_API_KEY_CODING`, `GEMINI_API_KEY_DOCS`; one shared `GEMINI_API_KEY` also works), and run one from the terminal:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
pal agent coding "how does checkout charge the card?" --file shop.zip
|
|
154
|
+
pal agent docs "write a README for this project" --file shop.zip
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The **SDK** (`pal.sdk`) is for building your own agents or bringing agents written with other frameworks.
|
|
158
|
+
|
|
159
|
+
- **Native agent** (written for Pal, uses the SDK's APIs): subclass `NativeAgent`, or use the ready-made `ReActAgent`
|
|
160
|
+
and `ReflexionAgent`.
|
|
161
|
+
- **Non-native agent** (written with another framework): adapt it, no changes to its code.
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from pal.llm_wrapper.components.base import WrapperConfig
|
|
165
|
+
from pal.sdk import AgentSDK, ReActAgent, adapt, autogen_model_client
|
|
166
|
+
|
|
167
|
+
sdk = AgentSDK.standalone(WrapperConfig(backend="gemini", model="gemini-3.5-flash", api_key="..."))
|
|
168
|
+
|
|
169
|
+
ReActAgent(sdk).run("what is 6 times 7?").answer # native pattern: reasons, calls tools, answers
|
|
170
|
+
|
|
171
|
+
with adapt("autogen", sdk): # AutoGen 0.2: your existing code, unchanged
|
|
172
|
+
...
|
|
173
|
+
with adapt("open-interpreter", sdk): # Open Interpreter
|
|
174
|
+
...
|
|
175
|
+
# AutoGen 0.4+: AssistantAgent("helper", model_client=autogen_model_client(sdk))
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
| Framework | How | Checked against the real library |
|
|
179
|
+
|---|---|---|
|
|
180
|
+
| AutoGen 0.2 (`pyautogen==0.2.35`) | `adapt("autogen", sdk)` | yes, a two-agent chat |
|
|
181
|
+
| AutoGen 0.4+ (`autogen-agentchat`) | `autogen_model_client(sdk)` | yes, an agent run |
|
|
182
|
+
| Open Interpreter 0.4 | `adapt("open-interpreter", sdk)` | yes, a chat turn |
|
|
183
|
+
| MetaGPT | `adapt("metagpt", sdk)` | no: could not be installed in the test environment, checked against a stand-in only |
|
|
184
|
+
| ReAct, Reflexion | native `ReActAgent`, `ReflexionAgent` | tested with scripted models |
|
|
185
|
+
|
|
186
|
+
**Where queries go.** The SDK routes by query type: model work (`LLMQuery`) goes to the Pal kernel; non-LLM work
|
|
187
|
+
(`OSQuery`: file operations, network requests, system facts) goes to the OS kernel, Ubuntu's Linux kernel here, through
|
|
188
|
+
a guarded interface. Files stay in a per-agent workspace (`~/.pal/workspaces/<agent>`), private network addresses are
|
|
189
|
+
blocked, and overwrite or delete asks for confirmation (default: no).
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
from pal.sdk import OSQuery, LLMQuery
|
|
193
|
+
|
|
194
|
+
sdk.os.write_file("notes/todo.txt", "buy milk") # OS kernel: a file operation, no model involved
|
|
195
|
+
sdk.os.http_get("https://example.com") # OS kernel: a network request
|
|
196
|
+
sdk.send_request(LLMQuery(messages=[{"role": "user", "content": "plan my day"}])) # Pal kernel: model work
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Keyboard and mouse control are not supported (they need a desktop session). The OS operations are not offered to the
|
|
200
|
+
chat's tools; `register_os_tools(sdk)` makes them available to ReAct-style agents you build.
|
|
201
|
+
|
|
202
|
+
**Architecture.** The diagram (`docs/architecture.png`, source `docs/architecture_figure.py`) shows the Application layer, the AIOS Kernel with its components, the OS Kernel
|
|
203
|
+
and the hardware. The kernel's blocks: LLM Wrapper (LiteLLM and OpenRouter), Local LLM, LLM Scheduler, Context Manager with Knowledge Graph and Compression, Notes,
|
|
204
|
+
Memory and Storage managers, Tool and Access managers, and the Token, Latency and Memory trackers.
|
|
205
|
+
|
|
206
|
+

|
|
207
|
+
|
|
208
|
+
**LLM Wrapper and Local LLM.** Every model call goes through LiteLLM's Python SDK, in three kinds of wrapper. *LiteLLM wrapper*: your own key
|
|
209
|
+
for one provider (OpenAI, Anthropic, Gemini, Groq, DeepSeek, Mistral, Together ...), direct. *OpenRouter wrapper*: one OpenRouter key reaches hundreds of
|
|
210
|
+
models, some free, with a model browser (`pal models --free`): the way to explore. *Local LLM*: models served on this machine (Ollama, vLLM,
|
|
211
|
+
LM Studio, llama.cpp) and the in-process Hugging Face model. Pick a mode with `pal chat --mode explore` or `--mode own_key`; `pal doctor` says which is ready. In Explore mode your prompts pass through OpenRouter. LiteLLM handles users' API keys, so it is pinned
|
|
212
|
+
(1.102.1), hash-locked (`requirements/litellm.lock`, installed first by `python run.py`), used as an SDK only (never its proxy), and checked by
|
|
213
|
+
`pal doctor`. If your provider is rate-limited or down, an optional fallback model answers. See `docs/ARCHITECTURE.md`.
|
|
214
|
+
|
|
215
|
+
**Context Manager, and the blocks around it.** One token budget over the history, the code-graph excerpts, document excerpts and notes. The
|
|
216
|
+
context manager keeps two jobs (which turns to show, and fitting everything under the budget) and asks the others: *Compression* shortens old
|
|
217
|
+
assistant replies by rule (no model: code bodies, replaced drafts and filler go; exact details stay; turns too old to show become a short facts
|
|
218
|
+
line), the *Knowledge Graph* supplies the matching excerpts of an uploaded project, and the *Notes Manager* supplies notes from other sessions and
|
|
219
|
+
owns everything about notes (what is kept, recalled, forgotten and tidied). Measured on a scripted 34-turn session it uses 49% fewer tokens than
|
|
220
|
+
sending everything and 15% more than plain paging, and keeps a figure given in turn 1 that paging loses (`experiments/compression_bench.py`).
|
|
221
|
+
|
|
222
|
+
**Three trackers.** The *Token Tracker* counts tokens and credits each saving to the part that made it, the *Latency Tracker* times every turn in
|
|
223
|
+
stages (routing, input saver, context, API, tools) so a slow turn can be explained, and the *Memory Tracker* reports the notes (RAM and disk), open
|
|
224
|
+
chats, indexed projects, storage and the process's own memory. Pal's `/tokens` shows them.
|
|
225
|
+
|
|
226
|
+
**The AIOS paper's 17 tools.** 12 are kept: Wikipedia and arXiv, and (off by default) Google search, WolframAlpha, currency, WordsAPI, moon
|
|
227
|
+
phase and five Hugging Face image and audio tools. Bing search, Google Places, IMDb rank, Shazam and TripAdvisor were removed. Google's own
|
|
228
|
+
search API is closed to new customers, so `google_search` reads results through SerpApi. No real service has been called by the tests:
|
|
229
|
+
see `docs/TOOLS.md`.
|
|
230
|
+
|
|
231
|
+
**Tools by name.** `pal tools` prints all 34 tools with human names (File Read Tool, Directory Read Tool, Document Search Tool, File to
|
|
232
|
+
Markdown Converter Tool, Code Graph Builder Tool, ...) and whether each is on. The input converter and graphify are tools too:
|
|
233
|
+
`file_to_markdown`, `build_code_graph`, `query_code_graph`. A chat's uploaded and generated files are deleted when the chat ends.
|
|
234
|
+
|
|
235
|
+
**Demo experiments.** `python run.py experiment rag` has a real local model build a small RAG engine, once through a plain chat client and once through
|
|
236
|
+
Pal, and reports the tokens saved. `python run.py experiment build` has a real local model (Ollama) write code, saves it to files in
|
|
237
|
+
`experiment_output/`, judges it with a project's tests, and compares a plain chat client with Pal on tokens, time and correctness. There is no
|
|
238
|
+
simulation. `python run.py experiment` runs a long question-and-answer session instead (a clearly labelled simulation if Ollama is not available).
|
|
239
|
+
Neither is part of the package: see `experiments/README.md`.
|
|
240
|
+
|
|
241
|
+
**Terminal chat.** `pal chat` (add `--agent coding`, `--file notes.md`); commands `/file`, `/agent`, `/reset`, `/stats`, `/quit`.
|
|
242
|
+
|
|
243
|
+
Limits: only text replies are redirected (framework tool calling is not), and non-native agents get the light savers
|
|
244
|
+
(tidying, optional repeat cache, stats), not the full pipeline, because the framework owns its prompts.
|
|
245
|
+
|
|
246
|
+
### Try it: the Experiment tab
|
|
247
|
+
|
|
248
|
+
Open the **Experiment** tab and press *Run demo*. It sends 6 realistic messages (plan a small launch, with an
|
|
249
|
+
attached survey) twice with the model you picked, once like a plain chat app and once through Pal, then shows the
|
|
250
|
+
tokens the API reported and the time taken for each, the saving, and the launch brief it produced. The **Chat** tab
|
|
251
|
+
shows a running "saved this chat" bar.
|
|
252
|
+
|
|
253
|
+
## Pal in the terminal
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
pip install pal-code # installs the `pal` command
|
|
257
|
+
pal cli # opens a session in the current folder
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
- **Three built-in agents, Build, Plan and Ask:** press **Tab** to switch. Build proposes file changes as a diff and writes them only when you answer `y`. Plan reads your folder and answers with a short plan. Ask answers questions about your code (or anything else) directly. Plan and Ask never change files.
|
|
261
|
+
### The build workflow (plans, context, sandbox, apply)
|
|
262
|
+
|
|
263
|
+
Plan, review and apply changes step by step:
|
|
264
|
+
|
|
265
|
+
1. **Plans:** every session works in a plan, saved per folder in `~/.pal/projects/`. `/plans`, `/new [name]`, `/current`, `/rename`, `/delete-plan`. Close the terminal and come back: the plan, its conversation and its pending changes are still there.
|
|
266
|
+
2. **Context:** `/load <files|dirs|globs> [-n note]` adds files to the plan's context, sent with every request (and only again when they change). `/ls`, `/rm`, `/clear`. At autonomy `semi` and above the Plan agent loads the files its plan names by itself.
|
|
267
|
+
3. **Plan agent:** writes numbered steps; `/continue` builds the next step, `/continue all` builds every step.
|
|
268
|
+
4. **Build agent:** changes go into a **sandbox**, not your files. `/diff` shows them, `/review` opens them as a page in your browser, `/reject <file>` drops one, `/rewind [id]` goes back, `/log` lists versions, `/convo` shows the conversation.
|
|
269
|
+
5. **Apply:** `/apply` writes the files, then runs the checks the Build agent suggested (tests, build), **only after you approve each one**. A failing check puts every file back; with `auto-debug` the Build agent fixes it and Pal tries again (up to 3 times). In a git repository Pal commits with a written message (`auto-commit`).
|
|
270
|
+
6. **Branches:** `/branches`, `/checkout <name>` (new branches start as a copy), `/delete-branch`, to try another approach without losing the first.
|
|
271
|
+
7. **Autonomy:** `/autonomy none|basic|plus|semi|full` (default `semi`) or single settings with `/set <name> on|off` (`auto-context`, `auto-continue`, `auto-apply`, `can-exec`, `auto-exec`, `auto-debug`, `auto-commit`). Only `full` runs checks without asking.
|
|
272
|
+
8. **Syntax check before review:** every file the Build agent writes must parse (Python, JSON, YAML, TOML, and with tree-sitter JavaScript,
|
|
273
|
+
TypeScript, Go, Rust, Java, Kotlin, C, C++, C#, Ruby, PHP, Swift, Scala, Lua, shell). A file that does not goes back to the Build agent
|
|
274
|
+
with the error, up to twice, before you see it; one still broken is marked "Syntax error" in `/diff`.
|
|
275
|
+
9. **`/debug <command>`:** runs the command; while it fails, the Build agent gets the output and proposes a fix, you approve it, and the
|
|
276
|
+
command runs again (up to 3 fixes). Still failing? Pal offers to put every file back. Example: `/debug npm test`.
|
|
277
|
+
10. **One terminal per plan:** a plan open in another Pal is not opened twice (a second terminal starts a new plan), so two terminals never
|
|
278
|
+
overwrite each other's changes.
|
|
279
|
+
|
|
280
|
+
- **The Ask agent asks back when it matters:** when a good answer depends on a choice only you can make, it shows a question card
|
|
281
|
+
(2 to 4 choices, the recommended one first, or type your own; arrow keys or a number, Enter, Esc to skip) and continues with your answer.
|
|
282
|
+
Build and Plan never stop to ask.
|
|
283
|
+
- **Keyboard:** ↑/↓ earlier messages (saved per folder, never with a key in them) · Esc Esc clears the box · Esc stops Pal while it works ·
|
|
284
|
+
Alt+Enter (or `\` then Enter) a new line · Tab switches agent · Shift+Tab cycles autonomy (none, basic, plus, semi) · `/` or Ctrl+P the
|
|
285
|
+
command menu (↑↓, Enter) · Ctrl+R searches earlier messages · Ctrl+Space talks · Ctrl+L clears the screen · `?` lists every shortcut.
|
|
286
|
+
- **Talk instead of typing:** Ctrl+Space (or `/voice`) records until Enter and puts the words in the box. Speech becomes text on this
|
|
287
|
+
computer with faster-whisper (`pip install "pal-code[voice]"`), or with your OpenAI or Groq key. The web chat and the Studio have a
|
|
288
|
+
microphone button that uses the same. Dictation apps such as Wispr Flow work in both without any setup: they type into the box.
|
|
289
|
+
- **Session commands (like Claude Code):** `/init` (start a `PAL.md`, the project's instructions for Pal, sent with the first request of
|
|
290
|
+
every session) · `/clear` (fresh conversation; `/clear-context` empties the loaded context) · `/compact [focus]` · `/btw <question>`
|
|
291
|
+
(a side question, not added) · `/cost` · `/context` · `/memory [edit]` · `/add-dir <folder>` · `/permissions` · `/config` ·
|
|
292
|
+
`/plan`, `/build`, `/ask` `[task]` · `/copy` · `/export [file]` · `/agents` · `/simplify` · `/status` · `/doctor` · `/resume [plan]` ·
|
|
293
|
+
`/voice` · `/shortcuts`.
|
|
294
|
+
- **@file** adds a file to your message. A file Pal already has is not sent again unless it changed.
|
|
295
|
+
- **Commands:** `/help`, `/mode`, `/model`, `/key`, `/add`, `/files`, `/security`, `/budget`, `/tokens`, `/project`, `/debug`, the workflow commands above, `/exit` (**Ctrl+P** starts a command; `\` then Enter, or Alt+Enter, for a new line; **Ctrl+D** leaves).
|
|
296
|
+
- **Any AI, any model:** local Ollama models as before, plus:
|
|
297
|
+
- an API provider: `/model openai:<model>`, `anthropic:`, `gemini:`, `groq:`, `deepseek:`, `mistral:`, `together:`, `openrouter:` (key from `OPENAI_API_KEY` etc.);
|
|
298
|
+
- anything LiteLLM knows (100+ providers: Azure, Bedrock, Vertex, xAI, Fireworks, Cohere ...): `/model litellm:xai/grok-4`, with that provider's usual key variable;
|
|
299
|
+
- any OpenAI-compatible endpoint (a company gateway, a hosted open model): `/endpoint https://host/v1`, then `/model custom:<model>` (key: `PAL_CUSTOM_API_KEY` or `/key custom <key>`);
|
|
300
|
+
- local OpenAI-style servers: `/model lmstudio:<model>`, `/model vllm:<model>`.
|
|
301
|
+
- **A model per agent:** `/model plan anthropic:<model>`, `/model build qwen3-coder:30b`, `/model ask groq:<model>` (same conversation; `default` to undo; saved for next time). `/agents` shows who uses what. Keys are never saved.
|
|
302
|
+
- From the command line: `pal cli --provider litellm --model xai/grok-4`.
|
|
303
|
+
- **Measure it:** `pal bench "add a slug() helper with a test"` runs the same task on the same model twice, as a plain chat (your source
|
|
304
|
+
pasted in, the whole conversation resent each time) and through Pal, each in a temporary copy of your folder, and prints the tokens the model
|
|
305
|
+
really used for each step. Add follow-ups with `--then "..."`; `--json` for the raw result (also saved in `~/.pal/bench/`).
|
|
306
|
+
- **One answer:** `pal ask "why does this fail?"`, or `cat error.log | pal ask "explain"`; `pal ask` uses the Ask agent; add `--plan` or `--build` for the others.
|
|
307
|
+
- **Tokens saved, live:** while Pal works, the line next to the spinner shows the tokens saved so far; each answer ends with `used N · saved ~N this request · total saved N (%)`, and the status bar keeps the running total.
|
|
308
|
+
- **Security:** keys never leave your computer (secrets files are never sent, key-shaped strings are hidden), every proposed file is checked for security mistakes before you approve it, `/security` audits the folder (`/security ai` for a model review), and `/budget` caps a session's tokens. See `SECURITY.md`.
|
|
309
|
+
- **Where they were saved:** `/tokens` breaks the session down by stage (trimmed message, old turns left out, shortened replies, only the relevant parts of files or code, @files not resent); `/tokens last` does the same for the last request, `/tokens turns` lists every request, `/tokens help` explains how it is counted. Savings are estimates against a plain chat that resends everything.
|
|
310
|
+
|
|
311
|
+
## What happens to a message
|
|
312
|
+
|
|
313
|
+
1. **No model needed?** Pure arithmetic and "what time is it" are answered directly (0 ms, 0 tokens).
|
|
314
|
+
2. **Routing.** Attachments, code and long text go to the API. Otherwise the local LLM classifies the task; easy
|
|
315
|
+
ones it answers itself (or replies ESCALATE). Unclear or failed classification goes to the API. The API model is told which earlier turns the local model handled.
|
|
316
|
+
3. **Reduce.** The local LLM strips filler from your message (rules in `input_savers/INPUT_RULES.md`). Every edit is
|
|
317
|
+
checked by deterministic guards (numbers, units, negations, code, URLs, pasted text) and a verifier call, and
|
|
318
|
+
reverted if it fails or does not save tokens.
|
|
319
|
+
4. **Attach only what matters.**
|
|
320
|
+
- *Documents* (PDF, Word, PowerPoint, Excel, HTML, ...): converted to markdown and indexed once. Small ones are
|
|
321
|
+
sent in full on the upload turn; big ones as a preview and outline. Later turns get only the matching chunks.
|
|
322
|
+
- *Code*: the folder Pal starts in, or a zip uploaded in the web chat, indexed locally with graphify (AST only, no LLM). Each question gets
|
|
323
|
+
the relevant graph nodes and code excerpts. About 1,500 tokens instead of about 52,000 on Pal's own terminal package (measured once).
|
|
324
|
+
- *Memory* from earlier sessions, when relevant.
|
|
325
|
+
5. **Page the history.** The last 6 turns are always sent. Older turns come back only if they match the question.
|
|
326
|
+
6. **API call**, with the output rules in `agent_constraints/components/AGENT_OUTPUT.md`. The model may call
|
|
327
|
+
tools (calculator, time, and, when a document or project is attached, `search_documents`, `read_document`, `read_source`, ...),
|
|
328
|
+
up to 3 rounds.
|
|
329
|
+
7. **Record.** History keeps the reduced message and a stub per file, never the attached bodies. Metrics get the
|
|
330
|
+
route, latencies and estimated savings. In Pal, `/tokens` shows them.
|
|
331
|
+
|
|
332
|
+
Savings from paging, documents and the code graph are **estimates** (characters / 4). Set `token_counter: provider`
|
|
333
|
+
for the model's own counts (an extra network call per count).
|
|
334
|
+
|
|
335
|
+
## Configuration
|
|
336
|
+
|
|
337
|
+
Defaults: `src/pal/config/default.yaml`. Override with `PAL_CONFIG=my.yaml`,
|
|
338
|
+
or with environment variables: `PAL__MEMORY__ENABLED=false`,
|
|
339
|
+
`PAL__CONTEXT__HOT_TURNS=10`. Unknown keys and bad values stop startup with a clear message.
|
|
340
|
+
`pal config` prints the effective settings.
|
|
341
|
+
|
|
342
|
+
Data (memory, indexed documents, code graphs) lives in `~/.pal`, or `PAL_HOME`.
|
|
343
|
+
|
|
344
|
+
## Privacy and security
|
|
345
|
+
|
|
346
|
+
- **Memory stores what you type**, on this machine, in `~/.pal`. It skips messages under 25 characters and anything
|
|
347
|
+
that looks like a key or password, and never stores attachments or model replies. Notes from other sessions that
|
|
348
|
+
match a question are sent to the API model inside that request. Turn it off with `memory.enabled: false`, or
|
|
349
|
+
wipe it by deleting `~/.pal/memory`.
|
|
350
|
+
- Tools are read-only. Their results, documents and memory are marked as data in the prompt, but a document can
|
|
351
|
+
still contain text that tries to steer the model; the tools cannot write, delete or reach the network.
|
|
352
|
+
- Uploads are size-limited; zips are extracted safely (no path escapes, symlinks, binaries).
|
|
353
|
+
|
|
354
|
+
## Operating systems
|
|
355
|
+
|
|
356
|
+
Pure Python, no shell scripts required. CI (`.github/workflows/ci.yml`) runs lint, types and tests on Linux, macOS
|
|
357
|
+
and Windows with Python 3.10 to 3.13. Where it differs:
|
|
358
|
+
|
|
359
|
+
| | Linux | macOS | Windows |
|
|
360
|
+
|---|---|---|---|
|
|
361
|
+
| Chat, documents, memory, tools, metrics | yes | yes | yes |
|
|
362
|
+
| Agent tool socket | Unix socket | Unix socket | loopback TCP |
|
|
363
|
+
| Agent resource limits (orchestrator only) | cgroup v2, needs root or sudo | not enforced | not enforced |
|
|
364
|
+
|
|
365
|
+
The chat does not use the orchestrator. The maintainer's environment for this refactor was Linux only: the
|
|
366
|
+
macOS and Windows columns are covered by code that avoids POSIX-only calls and by the CI matrix, not by a run.
|
|
367
|
+
|
|
368
|
+
## Layout, tests, development
|
|
369
|
+
|
|
370
|
+
`docs/ARCHITECTURE.md` gives the overview (start-up, the terminal session, the engine, the web, data); `docs/ENGINE.md` has every engine component and the design of a turn.
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
pip install -e ".[dev,full]"
|
|
374
|
+
pytest # ~470 tests, no network, no real model
|
|
375
|
+
ruff check src tests
|
|
376
|
+
mypy
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
The kernel-level work (patched Linux kernel, `/proc/pal_stats`) stays in a separate repo.
|