pal-code 0.1.1__tar.gz → 0.1.3__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.1 → pal_code-0.1.3}/LICENSE +1 -1
- {pal_code-0.1.1 → pal_code-0.1.3}/PKG-INFO +6 -6
- {pal_code-0.1.1 → pal_code-0.1.3}/pyproject.toml +7 -4
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/__init__.py +1 -1
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/cli.py +18 -13
- pal_code-0.1.3/src/pal/context_window.py +42 -0
- pal_code-0.1.3/src/pal/llm_wrapper/__init__.py +34 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/routes.py +2 -2
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/runs.py +21 -2
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/bench.py +8 -1
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/cli.py +300 -68
- pal_code-0.1.3/src/pal/terminal/logo.py +140 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/session.py +13 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/setup.py +129 -3
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/ui.py +102 -48
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/voice.py +3 -3
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/workflow.py +3 -3
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/app.py +6 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/studio.css +2 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/voice.js +1 -1
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/templates/index.html +2 -2
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/templates/studio.html +2 -2
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal_code.egg-info/PKG-INFO +6 -6
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal_code.egg-info/SOURCES.txt +1 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal_code.egg-info/requires.txt +4 -4
- pal_code-0.1.1/src/pal/llm_wrapper/__init__.py +0 -34
- pal_code-0.1.1/src/pal/terminal/logo.py +0 -117
- {pal_code-0.1.1 → pal_code-0.1.3}/README.md +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/setup.cfg +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/__main__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/access_manager/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/access_manager/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/access_manager/components/access_control.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/access_manager/components/base.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/access_manager/components/intervention.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/access_manager/components/privilege_registry.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/access_manager/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/access_manager/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/agent_constraints/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/agent_constraints/components/AGENT_OUTPUT.md +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/agent_constraints/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/agent_constraints/components/constraints.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/agent_constraints/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/agent_constraints/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/agents/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/agents/coding.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/agents/docs.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/chat/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/chat/demo.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/chat/providers.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/chat/service.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/chat/services/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/chat/services/base.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/chat/services/data.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/chat/services/media.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/chat/services/web.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/chat/sessions.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/chat/tools.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/chat/uploads.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/components/adverbs.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/components/hedges.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/components/interjections.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/components/minifier.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/components/output_compressor.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/components/pleonasms.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/components/punctuations.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/components/stopwords.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/history.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/utils/negations.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/utils/nltk_setup.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/utils/pronouns.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/utils/proselint_setup.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/compression/utils/spacy_setup.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/config/default.yaml +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/config.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/chat_context.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/components/assembler.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/components/context_cache.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/components/kv_bridge.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/components/pager.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/components/simple_context_manager.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/components/turns.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/utils/hashing.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/utils/relevance.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/context_manager/utils/storage.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/documents/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/documents/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/documents/components/chunker.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/documents/components/index.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/documents/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/errors.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_converters/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_converters/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_converters/components/base.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_converters/components/pandoc_converter.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_converters/components/pdf_converter.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_converters/components/pptx_converter.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_converters/components/xlsx_converter.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_converters/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_converters/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_converters/workspace.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_savers/INPUT_RULES.md +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_savers/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_savers/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_savers/components/base.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_savers/components/methods.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_savers/components/verifier.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_savers/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_savers/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/input_savers/utils/guards.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/knowledge_graph/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/knowledge_graph/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/knowledge_graph/components/base.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/knowledge_graph/components/builder.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/knowledge_graph/components/retriever.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/knowledge_graph/components/workspace.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/knowledge_graph/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/knowledge_graph/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/latency_tracker/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/latency_tracker/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_scheduler/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_scheduler/api.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_scheduler/code.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_scheduler/core.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_scheduler/local.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_scheduler/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_scheduler/types.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_wrapper/adapter.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_wrapper/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_wrapper/components/adapter_types.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_wrapper/components/base.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_wrapper/components/features.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_wrapper/components/litellm_wrapper.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_wrapper/components/openrouter_wrapper.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_wrapper/modes.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_wrapper/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_wrapper/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_wrapper/utils/registry.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/llm_wrapper/utils/token_counting.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/local_llm/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/local_llm/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/local_llm/components/huggingface_local.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/local_llm/components/local_llm.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/logging_setup.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory/components/lru_k.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory/components/manager.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory/components/note.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory/components/storage_manager.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory/utils/keyword_overlap.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory_tracker/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory_tracker/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory_tracker/components/process.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/memory_tracker/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/metrics/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/metrics/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/metrics/components/collector.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/metrics/components/exporter.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/metrics/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/metrics/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/notes_manager/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/notes_manager/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/notes_manager/components/privacy.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/notes_manager/components/recall.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/notes_manager/components/tidy.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/notes_manager/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/orchestrator/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/orchestrator/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/orchestrator/components/agent.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/orchestrator/components/cgroup_manager.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/orchestrator/components/context_interrupt.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/orchestrator/components/limits.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/orchestrator/components/scheduler.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/orchestrator/components/syscall_scheduler.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/orchestrator/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/orchestrator/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/orchestrator/utils/device.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/orchestrator/utils/protocol.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/os_kernel/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/os_kernel/filesystem.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/os_kernel/network.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/os_kernel/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/os_kernel/sysinfo.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/paths.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/py.typed +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/redact.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/adapters.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/agent.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/components/autogen_adapter.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/components/autogen_client.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/components/framework_adapter_base.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/components/metagpt_adapter.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/components/open_interpreter_adapter.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/components/tool_catalog.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/os_api.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/patterns.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/queries.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/savers.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/sdk/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/storage_manager/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/storage_manager/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/storage_manager/components/base.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/storage_manager/components/local_file_backend.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/storage_manager/components/storage_queue.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/storage_manager/components/vector_store_backend.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/storage_manager/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/storage_manager/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/storage_manager/utils/memory_adapter.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/storage_manager/utils/sdk.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/builder.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/catalog.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/checks.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/clients.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/editor.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/files.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/models.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/plan.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/planner.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/studio/policy.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/task_router/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/task_router/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/task_router/components/answerer.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/task_router/components/base.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/task_router/components/classifier.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/task_router/components/gates.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/task_router/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/task_router/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/backend.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/clients.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/commands.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/decide.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/files.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/flow_cli.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/hardware.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/history.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/keys.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/local_models.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/models.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/policy.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/project.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/review.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/security.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/syntax.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/terminal/theme.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/token_tracker/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/token_tracker/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/tokens.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/tool_catalog.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/tool_manager/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/tool_manager/builtin.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/tool_manager/components/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/tool_manager/components/base.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/tool_manager/components/conflict_resolver.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/tool_manager/components/param_validator.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/tool_manager/components/tool_call_queue.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/tool_manager/components/tool_registry.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/tool_manager/pipeline.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/tool_manager/utils/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/__init__.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/editor.js +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/fonts/LICENSE-Inter.txt +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/fonts/inter-400.woff2 +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/fonts/inter-500.woff2 +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/fonts/inter-600.woff2 +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/fonts/inter-700.woff2 +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/inter.css +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/pal-logo-256.png +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/pal-logo-32.png +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/pal-logo-64.png +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal/web/static/studio.js +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal_code.egg-info/dependency_links.txt +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal_code.egg-info/entry_points.txt +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/src/pal_code.egg-info/top_level.txt +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/tests/test_cli.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/tests/test_config.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/tests/test_lockfile.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/tests/test_paths.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/tests/test_redact.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/tests/test_run_script.py +0 -0
- {pal_code-0.1.1 → pal_code-0.1.3}/tests/test_tool_catalog.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pal-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
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:
|
|
5
|
+
Author: Vrushal More
|
|
6
6
|
License: MIT
|
|
7
7
|
Keywords: ai,coding-assistant,cli,llm,ollama,tokens,code-graph
|
|
8
8
|
Classifier: Development Status :: 4 - Beta
|
|
@@ -26,6 +26,9 @@ Requires-Dist: graphifyy>=0.9
|
|
|
26
26
|
Requires-Dist: pypdf>=4.0
|
|
27
27
|
Requires-Dist: python-pptx>=0.6.23
|
|
28
28
|
Requires-Dist: openpyxl>=3.1
|
|
29
|
+
Requires-Dist: sounddevice>=0.4
|
|
30
|
+
Requires-Dist: numpy>=1.24
|
|
31
|
+
Requires-Dist: faster-whisper>=1.0
|
|
29
32
|
Provides-Extra: documents
|
|
30
33
|
Requires-Dist: pymupdf4llm>=0.0.17; extra == "documents"
|
|
31
34
|
Provides-Extra: graph
|
|
@@ -42,11 +45,8 @@ Provides-Extra: inprocess
|
|
|
42
45
|
Requires-Dist: torch; extra == "inprocess"
|
|
43
46
|
Requires-Dist: transformers; extra == "inprocess"
|
|
44
47
|
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
48
|
Provides-Extra: full
|
|
49
|
-
Requires-Dist: pal-code[documents
|
|
49
|
+
Requires-Dist: pal-code[documents]; extra == "full"
|
|
50
50
|
Provides-Extra: dev
|
|
51
51
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
52
52
|
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
@@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pal-code"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.3"
|
|
8
8
|
description = "Pal: build and plan with AI in your terminal (pal cli) or browser (pal web), on a layer that cuts tokens and latency."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
license = { text = "MIT" }
|
|
12
|
-
authors = [{ name = "
|
|
12
|
+
authors = [{ name = "Vrushal More" }]
|
|
13
13
|
keywords = ["ai", "coding-assistant", "cli", "llm", "ollama", "tokens", "code-graph"]
|
|
14
14
|
classifiers = [
|
|
15
15
|
"Development Status :: 4 - Beta",
|
|
@@ -32,6 +32,9 @@ dependencies = [
|
|
|
32
32
|
"pypdf>=4.0", # PDF -> markdown
|
|
33
33
|
"python-pptx>=0.6.23", # PowerPoint -> markdown
|
|
34
34
|
"openpyxl>=3.1", # Excel -> markdown
|
|
35
|
+
"sounddevice>=0.4", # the mic: recording (PortAudio comes with it on Windows and macOS)
|
|
36
|
+
"numpy>=1.24",
|
|
37
|
+
"faster-whisper>=1.0", # speech to text on this computer (Whisper); nothing leaves the computer
|
|
35
38
|
]
|
|
36
39
|
|
|
37
40
|
[project.optional-dependencies]
|
|
@@ -42,8 +45,8 @@ litellm = [] # kept so older install lines still work: litel
|
|
|
42
45
|
vector = ["chromadb"]
|
|
43
46
|
embeddings = ["sentence-transformers"]
|
|
44
47
|
inprocess = ["torch", "transformers"]
|
|
45
|
-
voice = [
|
|
46
|
-
full = ["pal-code[documents
|
|
48
|
+
voice = [] # kept so older install lines still work: the mic is installed by default now
|
|
49
|
+
full = ["pal-code[documents]"]
|
|
47
50
|
dev = ["pytest>=8", "ruff>=0.5", "mypy>=1.10", "types-requests", "types-PyYAML"]
|
|
48
51
|
|
|
49
52
|
[project.scripts]
|
|
@@ -212,7 +212,8 @@ def load_dotenv(path: str | os.PathLike | None = None, env=None) -> list[str]:
|
|
|
212
212
|
return loaded
|
|
213
213
|
|
|
214
214
|
|
|
215
|
-
def _serve(settings: Settings, open_browser: bool = False, page: str = "", graph=None, documents: list | None = None
|
|
215
|
+
def _serve(settings: Settings, open_browser: bool = False, page: str = "", graph=None, documents: list | None = None, project_dir=None,
|
|
216
|
+
background=None) -> int:
|
|
216
217
|
from pal.chat import ChatService
|
|
217
218
|
from pal.web import create_app
|
|
218
219
|
|
|
@@ -221,7 +222,10 @@ def _serve(settings: Settings, open_browser: bool = False, page: str = "", graph
|
|
|
221
222
|
service = ChatService(settings, graph=graph) if graph is not None else ChatService(settings)
|
|
222
223
|
if documents:
|
|
223
224
|
service.preload_docs = list(documents)
|
|
224
|
-
app = create_app(service)
|
|
225
|
+
app = create_app(service, studio={"project_dir": project_dir}) if project_dir else create_app(service)
|
|
226
|
+
if background is not None: # pal web: the folder's setup runs while the page is already usable
|
|
227
|
+
import threading as _bg
|
|
228
|
+
_bg.Thread(target=background, args=(service,), daemon=True, name="pal-web-setup").start()
|
|
225
229
|
if s.host not in _LOOPBACK:
|
|
226
230
|
print(f"WARNING: listening on {s.host}. Pal has no login: anyone who can reach this port can use "
|
|
227
231
|
"your API keys' quota and read stored memory. Put it behind an authenticating reverse proxy.",
|
|
@@ -229,20 +233,21 @@ def _serve(settings: Settings, open_browser: bool = False, page: str = "", graph
|
|
|
229
233
|
shown = "localhost" if s.host in ("0.0.0.0", "::") else s.host # noqa: S104
|
|
230
234
|
url = f"http://{shown}:{s.port}" + ("/" + page.strip("/") if page else "")
|
|
231
235
|
print(f"Pal {__version__} on {url} (Ctrl+C to stop)")
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
236
|
+
if background is None: # pal serve: say what is set up; pal web says nothing more and starts at once
|
|
237
|
+
from pal.chat.providers import API_PROVIDERS
|
|
238
|
+
keys = [p for p, var in API_PROVIDERS.items() if os.environ.get(var)]
|
|
239
|
+
print("API key found for: " + ", ".join(keys) if keys else
|
|
240
|
+
"No API key in the environment: paste one in the page (API key menu), or set e.g. GEMINI_API_KEY.")
|
|
241
|
+
status = service.local_status()
|
|
242
|
+
if status["ok"] is False:
|
|
243
|
+
print(f"WARNING: local model: {status['detail']}. Input reduction and local answers are off until it runs; "
|
|
244
|
+
"the app still works and sends everything to the API model.", file=sys.stderr)
|
|
245
|
+
else:
|
|
246
|
+
print(f"Local model: {status['detail']}")
|
|
242
247
|
if open_browser:
|
|
243
248
|
import threading
|
|
244
249
|
import webbrowser
|
|
245
|
-
threading.Timer(
|
|
250
|
+
threading.Timer(0.3, lambda: webbrowser.open(url)).start()
|
|
246
251
|
try:
|
|
247
252
|
try:
|
|
248
253
|
from waitress import serve
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""How many tokens a model can take in one request (its context window), for the "tokens left" counters in the terminal and the web page.
|
|
2
|
+
|
|
3
|
+
API models: the size LiteLLM knows for the model, else a safe default. Local models: the context Pal gives Ollama (num_ctx), which is what
|
|
4
|
+
really limits them here, whatever the model could do on paper."""
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from functools import lru_cache
|
|
8
|
+
|
|
9
|
+
LOCAL_CONTEXT = 8192 # Pal runs local models with num_ctx 8192 (pal.terminal.backend.make_core)
|
|
10
|
+
API_DEFAULT = 128_000 # a model LiteLLM does not know: most current API models take at least this
|
|
11
|
+
LOCAL_PROVIDERS = ("local", "ollama", "lmstudio", "vllm", "llamacpp", "llama.cpp", "huggingface")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@lru_cache(maxsize=256)
|
|
15
|
+
def context_window(provider: str, model: str) -> int:
|
|
16
|
+
provider = (provider or "").lower()
|
|
17
|
+
if provider in LOCAL_PROVIDERS:
|
|
18
|
+
return LOCAL_CONTEXT
|
|
19
|
+
if not model:
|
|
20
|
+
return API_DEFAULT
|
|
21
|
+
try:
|
|
22
|
+
import litellm
|
|
23
|
+
for name in (f"{provider}/{model}" if provider else model, model, model.split("/")[-1]):
|
|
24
|
+
try:
|
|
25
|
+
info = litellm.get_model_info(name)
|
|
26
|
+
except Exception: # noqa: BLE001 (not in LiteLLM's table under this name)
|
|
27
|
+
continue
|
|
28
|
+
size = info.get("max_input_tokens") or info.get("max_tokens")
|
|
29
|
+
if size:
|
|
30
|
+
return int(size)
|
|
31
|
+
except Exception: # noqa: BLE001 (LiteLLM missing or broken: the default)
|
|
32
|
+
pass
|
|
33
|
+
return API_DEFAULT
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def tokens_left(window: int, last_prompt: int) -> int:
|
|
37
|
+
"""What is left of the window after the last request's input (the next one is usually at least as big)."""
|
|
38
|
+
return max(0, window - max(0, last_prompt))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def short(n: int) -> str:
|
|
42
|
+
return f"{n / 1000:.1f}k".replace(".0k", "k") if n >= 10_000 else f"{n:,}"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""The model layer. Its names are loaded on first use (PEP 562), so importing a light submodule such as pal.llm_wrapper.modes (the provider
|
|
2
|
+
names and key variables) does not load the whole model stack: pal cli draws its first screen before any of it is needed."""
|
|
3
|
+
from importlib import import_module
|
|
4
|
+
|
|
5
|
+
_WHERE = {
|
|
6
|
+
"LLMAdapter": "pal.llm_wrapper.adapter",
|
|
7
|
+
"LLMAdapterResponse": "pal.llm_wrapper.components.adapter_types",
|
|
8
|
+
"LLMAdapterSyscall": "pal.llm_wrapper.components.adapter_types",
|
|
9
|
+
"LLMConfig": "pal.llm_wrapper.components.adapter_types",
|
|
10
|
+
"RouterStrategy": "pal.llm_wrapper.components.adapter_types",
|
|
11
|
+
"DeploymentType": "pal.llm_wrapper.components.base",
|
|
12
|
+
"LLMResponse": "pal.llm_wrapper.components.base",
|
|
13
|
+
"LLMSyscall": "pal.llm_wrapper.components.base",
|
|
14
|
+
"LLMWrapper": "pal.llm_wrapper.components.base",
|
|
15
|
+
"WrapperCapabilities": "pal.llm_wrapper.components.base",
|
|
16
|
+
"WrapperConfig": "pal.llm_wrapper.components.base",
|
|
17
|
+
"LLMWrapperPipeline": "pal.llm_wrapper.pipeline",
|
|
18
|
+
"available_backends": "pal.llm_wrapper.utils.registry",
|
|
19
|
+
"build_wrapper": "pal.llm_wrapper.utils.registry",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
__all__ = list(_WHERE)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def __getattr__(name: str):
|
|
26
|
+
if name in _WHERE:
|
|
27
|
+
value = getattr(import_module(_WHERE[name]), name)
|
|
28
|
+
globals()[name] = value
|
|
29
|
+
return value
|
|
30
|
+
raise AttributeError(f"module 'pal.llm_wrapper' has no attribute {name!r}")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def __dir__():
|
|
34
|
+
return sorted(set(globals()) | set(_WHERE))
|
|
@@ -49,7 +49,7 @@ def clean_references(raw) -> list[dict]:
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
def register_studio(app, service, *, planner_core: Callable | None = None, core_factory: Callable | None = None, discover_fn: Callable | None = None,
|
|
52
|
-
hot_turns: int | None = None) -> RunStore:
|
|
52
|
+
hot_turns: int | None = None, project_dir: Path | None = None) -> RunStore:
|
|
53
53
|
"""Add the Studio page and endpoints to the app. The three callables are for tests: the planner's model, the builder's model, local-model discovery."""
|
|
54
54
|
cfg = service.settings
|
|
55
55
|
home = Path(cfg.storage_dir).expanduser() if cfg.storage_dir else data_dir()
|
|
@@ -71,7 +71,7 @@ def register_studio(app, service, *, planner_core: Callable | None = None, core_
|
|
|
71
71
|
raise UserInputError("no local model is chosen: start Ollama and pull a model, or switch to an API model")
|
|
72
72
|
return local_core(m["model"], num_ctx())
|
|
73
73
|
|
|
74
|
-
runs = RunStore(home / "studio", core_factory or default_core_factory, max_runs=cfg.studio.max_runs, hot_turns=hot_turns)
|
|
74
|
+
runs = RunStore(home / "studio", core_factory or default_core_factory, max_runs=cfg.studio.max_runs, hot_turns=hot_turns, project_dir=project_dir)
|
|
75
75
|
app.extensions["studio_runs"] = runs
|
|
76
76
|
|
|
77
77
|
def local() -> dict:
|
|
@@ -95,9 +95,22 @@ class Run:
|
|
|
95
95
|
return self.arms[name]
|
|
96
96
|
|
|
97
97
|
|
|
98
|
+
def build_target(project: Path, folder: str) -> Path:
|
|
99
|
+
"""Where a build is written in the folder Pal was started in: the folder itself when it is empty, else a new subfolder named after the
|
|
100
|
+
product (with -2, -3 ... when that name is taken), so nothing that is already there is overwritten."""
|
|
101
|
+
project = Path(project)
|
|
102
|
+
if not any(p for p in project.iterdir() if not p.name.startswith(".")):
|
|
103
|
+
return project
|
|
104
|
+
target, n = project / folder, 2
|
|
105
|
+
while target.exists() and (not target.is_dir() or any(target.iterdir())):
|
|
106
|
+
target, n = project / f"{folder}-{n}", n + 1
|
|
107
|
+
return target
|
|
108
|
+
|
|
109
|
+
|
|
98
110
|
class RunStore:
|
|
99
|
-
def __init__(self, root: Path, core_factory: Callable, max_runs: int = 6, hot_turns: int | None = None):
|
|
111
|
+
def __init__(self, root: Path, core_factory: Callable, max_runs: int = 6, hot_turns: int | None = None, project_dir: Path | None = None):
|
|
100
112
|
self.root, self.core_factory, self.max_runs, self.hot_turns = Path(root), core_factory, max_runs, hot_turns
|
|
113
|
+
self.project_dir = Path(project_dir).resolve() if project_dir else None # pal web's folder: the build is written there
|
|
101
114
|
self._runs: dict[str, Run] = {}
|
|
102
115
|
self._editors: dict[tuple[str, str], EditorSession] = {}
|
|
103
116
|
self._lock = threading.Lock()
|
|
@@ -140,11 +153,17 @@ class RunStore:
|
|
|
140
153
|
break
|
|
141
154
|
policy = Policy(dict(plan["permissions"]))
|
|
142
155
|
save = plan["permissions"].get("write_project")
|
|
143
|
-
|
|
156
|
+
where = None
|
|
157
|
+
if save:
|
|
158
|
+
where = (build_target(self.project_dir, plan["product"]["folder"]) if self.project_dir and arm != "baseline"
|
|
159
|
+
else self.root / run.id / arm / plan["product"]["folder"]) # the plain client's comparison copy stays in Pal's folder
|
|
160
|
+
state = ArmState(arm, label, where)
|
|
144
161
|
run.arms[arm] = state
|
|
145
162
|
if state.workspace:
|
|
146
163
|
state.workspace.mkdir(parents=True, exist_ok=True)
|
|
147
164
|
run.emit("arm_start", f"{label}: starting" if twice else "Starting", arm=arm)
|
|
165
|
+
if state.workspace and self.project_dir and arm != "baseline":
|
|
166
|
+
run.emit("saved_to", f"Files are written to {state.workspace}", arm=arm, path=str(state.workspace))
|
|
148
167
|
client: PlainClient | PalClient
|
|
149
168
|
if arm == "baseline":
|
|
150
169
|
client = PlainClient(core, SYSTEM)
|
|
@@ -67,6 +67,7 @@ class BenchResult:
|
|
|
67
67
|
plain: Arm
|
|
68
68
|
pal: Arm
|
|
69
69
|
when: float = field(default_factory=time.time)
|
|
70
|
+
pal_files: dict = field(default_factory=dict, repr=False) # what Pal's way wrote: {path: bytes}, offered to keep in your folder
|
|
70
71
|
|
|
71
72
|
@property
|
|
72
73
|
def saved(self) -> int:
|
|
@@ -78,6 +79,7 @@ class BenchResult:
|
|
|
78
79
|
|
|
79
80
|
def to_dict(self) -> dict:
|
|
80
81
|
d = asdict(self)
|
|
82
|
+
d.pop("pal_files", None)
|
|
81
83
|
d.update(saved=self.saved, saved_pct=self.saved_pct, plain_total=self.plain.total, pal_total=self.pal.total)
|
|
82
84
|
return d
|
|
83
85
|
|
|
@@ -161,7 +163,12 @@ def run_bench(folder: Path, task: str, core_factory: Callable[[], Any], model: s
|
|
|
161
163
|
pal_arm = _run_arm("pal", pal, steps, progress)
|
|
162
164
|
finally:
|
|
163
165
|
client.close()
|
|
164
|
-
|
|
166
|
+
kept = {}
|
|
167
|
+
for rel in sorted({f for st in pal_arm.steps for f in st.files}):
|
|
168
|
+
f = pal_dir / rel
|
|
169
|
+
if f.is_file():
|
|
170
|
+
kept[rel] = f.read_bytes()
|
|
171
|
+
result = BenchResult(task, model, str(folder), plain_arm, pal_arm, pal_files=kept)
|
|
165
172
|
save(result, home)
|
|
166
173
|
return result
|
|
167
174
|
|