@syrin/cli 1.3.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/LICENSE +15 -0
- package/README.md +302 -0
- package/dist/cli/commands/analyse.d.ts +16 -0
- package/dist/cli/commands/analyse.js +61 -0
- package/dist/cli/commands/dev.d.ts +23 -0
- package/dist/cli/commands/dev.js +419 -0
- package/dist/cli/commands/doctor.d.ts +10 -0
- package/dist/cli/commands/doctor.js +195 -0
- package/dist/cli/commands/index.d.ts +12 -0
- package/dist/cli/commands/index.js +12 -0
- package/dist/cli/commands/init.d.ts +16 -0
- package/dist/cli/commands/init.js +90 -0
- package/dist/cli/commands/list.d.ts +15 -0
- package/dist/cli/commands/list.js +50 -0
- package/dist/cli/commands/rollback.d.ts +12 -0
- package/dist/cli/commands/rollback.js +101 -0
- package/dist/cli/commands/test.d.ts +31 -0
- package/dist/cli/commands/test.js +88 -0
- package/dist/cli/commands/update.d.ts +9 -0
- package/dist/cli/commands/update.js +76 -0
- package/dist/cli/index.d.ts +13 -0
- package/dist/cli/index.js +342 -0
- package/dist/cli/prompts/index.d.ts +5 -0
- package/dist/cli/prompts/index.js +5 -0
- package/dist/cli/prompts/init-prompt.d.ts +17 -0
- package/dist/cli/prompts/init-prompt.js +263 -0
- package/dist/cli/utils/command-error-handler.d.ts +14 -0
- package/dist/cli/utils/command-error-handler.js +35 -0
- package/dist/cli/utils/common-types.d.ts +24 -0
- package/dist/cli/utils/common-types.js +6 -0
- package/dist/cli/utils/connection-handler.d.ts +37 -0
- package/dist/cli/utils/connection-handler.js +90 -0
- package/dist/cli/utils/index.d.ts +11 -0
- package/dist/cli/utils/index.js +11 -0
- package/dist/cli/utils/option-parsers.d.ts +41 -0
- package/dist/cli/utils/option-parsers.js +92 -0
- package/dist/cli/utils/output-utils.d.ts +12 -0
- package/dist/cli/utils/output-utils.js +21 -0
- package/dist/cli/utils/transport-resolver.d.ts +33 -0
- package/dist/cli/utils/transport-resolver.js +82 -0
- package/dist/cli/utils/version-banner.d.ts +10 -0
- package/dist/cli/utils/version-banner.js +26 -0
- package/dist/config/env-checker.d.ts +37 -0
- package/dist/config/env-checker.js +136 -0
- package/dist/config/generator.d.ts +19 -0
- package/dist/config/generator.js +196 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.js +9 -0
- package/dist/config/loader.d.ts +19 -0
- package/dist/config/loader.js +57 -0
- package/dist/config/schema.d.ts +42 -0
- package/dist/config/schema.js +181 -0
- package/dist/config/syrin.template.yaml +127 -0
- package/dist/config/types.d.ts +87 -0
- package/dist/config/types.js +6 -0
- package/dist/constants/app.d.ts +9 -0
- package/dist/constants/app.js +9 -0
- package/dist/constants/commands.d.ts +43 -0
- package/dist/constants/commands.js +43 -0
- package/dist/constants/defaults.d.ts +18 -0
- package/dist/constants/defaults.js +18 -0
- package/dist/constants/env-vars.d.ts +11 -0
- package/dist/constants/env-vars.js +11 -0
- package/dist/constants/icons.d.ts +23 -0
- package/dist/constants/icons.js +23 -0
- package/dist/constants/index.d.ts +17 -0
- package/dist/constants/index.js +17 -0
- package/dist/constants/labels.d.ts +38 -0
- package/dist/constants/labels.js +42 -0
- package/dist/constants/links.d.ts +10 -0
- package/dist/constants/links.js +11 -0
- package/dist/constants/list.d.ts +10 -0
- package/dist/constants/list.js +9 -0
- package/dist/constants/llm.d.ts +26 -0
- package/dist/constants/llm.js +25 -0
- package/dist/constants/messages.d.ts +107 -0
- package/dist/constants/messages.js +138 -0
- package/dist/constants/paths.d.ts +29 -0
- package/dist/constants/paths.js +29 -0
- package/dist/constants/transport.d.ts +9 -0
- package/dist/constants/transport.js +8 -0
- package/dist/events/emitter.d.ts +64 -0
- package/dist/events/emitter.js +142 -0
- package/dist/events/event-type.d.ts +66 -0
- package/dist/events/event-type.js +81 -0
- package/dist/events/payloads/diagnostics.d.ts +24 -0
- package/dist/events/payloads/diagnostics.js +5 -0
- package/dist/events/payloads/index.d.ts +15 -0
- package/dist/events/payloads/index.js +6 -0
- package/dist/events/payloads/llm.d.ts +58 -0
- package/dist/events/payloads/llm.js +6 -0
- package/dist/events/payloads/registry.d.ts +28 -0
- package/dist/events/payloads/registry.js +5 -0
- package/dist/events/payloads/session.d.ts +32 -0
- package/dist/events/payloads/session.js +5 -0
- package/dist/events/payloads/testing.d.ts +17 -0
- package/dist/events/payloads/testing.js +5 -0
- package/dist/events/payloads/tool.d.ts +29 -0
- package/dist/events/payloads/tool.js +5 -0
- package/dist/events/payloads/transport.d.ts +30 -0
- package/dist/events/payloads/transport.js +5 -0
- package/dist/events/payloads/validation.d.ts +37 -0
- package/dist/events/payloads/validation.js +5 -0
- package/dist/events/payloads/workflow.d.ts +45 -0
- package/dist/events/payloads/workflow.js +5 -0
- package/dist/events/store/file-store.d.ts +37 -0
- package/dist/events/store/file-store.js +113 -0
- package/dist/events/store/index.d.ts +7 -0
- package/dist/events/store/index.js +6 -0
- package/dist/events/store/memory-store.d.ts +26 -0
- package/dist/events/store/memory-store.js +39 -0
- package/dist/events/store.d.ts +11 -0
- package/dist/events/store.js +2 -0
- package/dist/events/types.d.ts +14 -0
- package/dist/events/types.js +2 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +30 -0
- package/dist/presentation/analysis-ui.d.ts +24 -0
- package/dist/presentation/analysis-ui.js +158 -0
- package/dist/presentation/dev/chat-ui-types.d.ts +68 -0
- package/dist/presentation/dev/chat-ui-types.js +5 -0
- package/dist/presentation/dev/chat-ui.d.ts +61 -0
- package/dist/presentation/dev/chat-ui.js +714 -0
- package/dist/presentation/dev/components/assistant-message.d.ts +19 -0
- package/dist/presentation/dev/components/assistant-message.js +36 -0
- package/dist/presentation/dev/components/header.d.ts +16 -0
- package/dist/presentation/dev/components/header.js +22 -0
- package/dist/presentation/dev/components/index.d.ts +13 -0
- package/dist/presentation/dev/components/index.js +13 -0
- package/dist/presentation/dev/components/input-panel.d.ts +22 -0
- package/dist/presentation/dev/components/input-panel.js +43 -0
- package/dist/presentation/dev/components/message-component.d.ts +16 -0
- package/dist/presentation/dev/components/message-component.js +51 -0
- package/dist/presentation/dev/components/messages-list.d.ts +24 -0
- package/dist/presentation/dev/components/messages-list.js +48 -0
- package/dist/presentation/dev/components/system-message.d.ts +16 -0
- package/dist/presentation/dev/components/system-message.js +26 -0
- package/dist/presentation/dev/components/user-message.d.ts +21 -0
- package/dist/presentation/dev/components/user-message.js +35 -0
- package/dist/presentation/dev/components/welcome-banner.d.ts +24 -0
- package/dist/presentation/dev/components/welcome-banner.js +146 -0
- package/dist/presentation/dev/goodbye-messages.d.ts +31 -0
- package/dist/presentation/dev/goodbye-messages.js +100 -0
- package/dist/presentation/dev/index.d.ts +5 -0
- package/dist/presentation/dev/index.js +5 -0
- package/dist/presentation/dev/text-wrapper.d.ts +30 -0
- package/dist/presentation/dev/text-wrapper.js +74 -0
- package/dist/presentation/dev-ui.d.ts +33 -0
- package/dist/presentation/dev-ui.js +246 -0
- package/dist/presentation/doctor-ui.d.ts +40 -0
- package/dist/presentation/doctor-ui.js +157 -0
- package/dist/presentation/init-ui.d.ts +14 -0
- package/dist/presentation/init-ui.js +41 -0
- package/dist/presentation/list-ui.d.ts +44 -0
- package/dist/presentation/list-ui.js +139 -0
- package/dist/presentation/test-ui.d.ts +49 -0
- package/dist/presentation/test-ui.js +358 -0
- package/dist/runtime/analysis/analyser.d.ts +14 -0
- package/dist/runtime/analysis/analyser.js +88 -0
- package/dist/runtime/analysis/dependencies.d.ts +10 -0
- package/dist/runtime/analysis/dependencies.js +140 -0
- package/dist/runtime/analysis/index.d.ts +10 -0
- package/dist/runtime/analysis/index.js +10 -0
- package/dist/runtime/analysis/indexer.d.ts +10 -0
- package/dist/runtime/analysis/indexer.js +62 -0
- package/dist/runtime/analysis/loader.d.ts +15 -0
- package/dist/runtime/analysis/loader.js +47 -0
- package/dist/runtime/analysis/normalizer.d.ts +14 -0
- package/dist/runtime/analysis/normalizer.js +184 -0
- package/dist/runtime/analysis/rules/__test-helpers__.d.ts +18 -0
- package/dist/runtime/analysis/rules/__test-helpers__.js +40 -0
- package/dist/runtime/analysis/rules/base.d.ts +38 -0
- package/dist/runtime/analysis/rules/base.js +23 -0
- package/dist/runtime/analysis/rules/error-codes.d.ts +64 -0
- package/dist/runtime/analysis/rules/error-codes.js +73 -0
- package/dist/runtime/analysis/rules/errors/e000-tool-not-found.d.ts +35 -0
- package/dist/runtime/analysis/rules/errors/e000-tool-not-found.js +32 -0
- package/dist/runtime/analysis/rules/errors/e001-missing-output-schema.d.ts +22 -0
- package/dist/runtime/analysis/rules/errors/e001-missing-output-schema.js +30 -0
- package/dist/runtime/analysis/rules/errors/e002-underspecified-input.d.ts +24 -0
- package/dist/runtime/analysis/rules/errors/e002-underspecified-input.js +52 -0
- package/dist/runtime/analysis/rules/errors/e003-type-mismatch.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e003-type-mismatch.js +73 -0
- package/dist/runtime/analysis/rules/errors/e004-free-text-propagation.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e004-free-text-propagation.js +47 -0
- package/dist/runtime/analysis/rules/errors/e005-tool-ambiguity.d.ts +25 -0
- package/dist/runtime/analysis/rules/errors/e005-tool-ambiguity.js +73 -0
- package/dist/runtime/analysis/rules/errors/e006-param-not-in-description.d.ts +22 -0
- package/dist/runtime/analysis/rules/errors/e006-param-not-in-description.js +57 -0
- package/dist/runtime/analysis/rules/errors/e007-output-not-guaranteed.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e007-output-not-guaranteed.js +56 -0
- package/dist/runtime/analysis/rules/errors/e008-circular-dependency.d.ts +22 -0
- package/dist/runtime/analysis/rules/errors/e008-circular-dependency.js +84 -0
- package/dist/runtime/analysis/rules/errors/e009-implicit-user-input.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e009-implicit-user-input.js +89 -0
- package/dist/runtime/analysis/rules/errors/e010-non-serializable.d.ts +25 -0
- package/dist/runtime/analysis/rules/errors/e010-non-serializable.js +46 -0
- package/dist/runtime/analysis/rules/errors/e011-missing-tool-description.d.ts +24 -0
- package/dist/runtime/analysis/rules/errors/e011-missing-tool-description.js +33 -0
- package/dist/runtime/analysis/rules/errors/e012-side-effect-detected.d.ts +39 -0
- package/dist/runtime/analysis/rules/errors/e012-side-effect-detected.js +40 -0
- package/dist/runtime/analysis/rules/errors/e013-non-deterministic-output.d.ts +37 -0
- package/dist/runtime/analysis/rules/errors/e013-non-deterministic-output.js +34 -0
- package/dist/runtime/analysis/rules/errors/e013-output-explosion.d.ts +39 -0
- package/dist/runtime/analysis/rules/errors/e013-output-explosion.js +36 -0
- package/dist/runtime/analysis/rules/errors/e014-hidden-dependency.d.ts +42 -0
- package/dist/runtime/analysis/rules/errors/e014-hidden-dependency.js +46 -0
- package/dist/runtime/analysis/rules/errors/e014-output-explosion.d.ts +39 -0
- package/dist/runtime/analysis/rules/errors/e014-output-explosion.js +36 -0
- package/dist/runtime/analysis/rules/errors/e015-hidden-dependency.d.ts +42 -0
- package/dist/runtime/analysis/rules/errors/e015-hidden-dependency.js +46 -0
- package/dist/runtime/analysis/rules/errors/e015-unbounded-execution.d.ts +44 -0
- package/dist/runtime/analysis/rules/errors/e015-unbounded-execution.js +66 -0
- package/dist/runtime/analysis/rules/errors/e016-output-validation-failed.d.ts +43 -0
- package/dist/runtime/analysis/rules/errors/e016-output-validation-failed.js +42 -0
- package/dist/runtime/analysis/rules/errors/e016-unbounded-execution.d.ts +44 -0
- package/dist/runtime/analysis/rules/errors/e016-unbounded-execution.js +66 -0
- package/dist/runtime/analysis/rules/errors/e017-input-validation-failed.d.ts +57 -0
- package/dist/runtime/analysis/rules/errors/e017-input-validation-failed.js +80 -0
- package/dist/runtime/analysis/rules/errors/e017-output-validation-failed.d.ts +43 -0
- package/dist/runtime/analysis/rules/errors/e017-output-validation-failed.js +42 -0
- package/dist/runtime/analysis/rules/errors/e018-input-validation-failed.d.ts +57 -0
- package/dist/runtime/analysis/rules/errors/e018-input-validation-failed.js +80 -0
- package/dist/runtime/analysis/rules/errors/e018-tool-execution-failed.d.ts +38 -0
- package/dist/runtime/analysis/rules/errors/e018-tool-execution-failed.js +37 -0
- package/dist/runtime/analysis/rules/errors/e019-tool-execution-failed.d.ts +38 -0
- package/dist/runtime/analysis/rules/errors/e019-tool-execution-failed.js +37 -0
- package/dist/runtime/analysis/rules/errors/e019-unexpected-test-result.d.ts +65 -0
- package/dist/runtime/analysis/rules/errors/e019-unexpected-test-result.js +109 -0
- package/dist/runtime/analysis/rules/errors/e020-unexpected-test-result.d.ts +65 -0
- package/dist/runtime/analysis/rules/errors/e020-unexpected-test-result.js +109 -0
- package/dist/runtime/analysis/rules/errors/e100-missing-output-schema.d.ts +22 -0
- package/dist/runtime/analysis/rules/errors/e100-missing-output-schema.js +30 -0
- package/dist/runtime/analysis/rules/errors/e101-missing-tool-description.d.ts +24 -0
- package/dist/runtime/analysis/rules/errors/e101-missing-tool-description.js +33 -0
- package/dist/runtime/analysis/rules/errors/e102-underspecified-input.d.ts +24 -0
- package/dist/runtime/analysis/rules/errors/e102-underspecified-input.js +52 -0
- package/dist/runtime/analysis/rules/errors/e103-type-mismatch.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e103-type-mismatch.js +72 -0
- package/dist/runtime/analysis/rules/errors/e104-param-not-in-description.d.ts +22 -0
- package/dist/runtime/analysis/rules/errors/e104-param-not-in-description.js +57 -0
- package/dist/runtime/analysis/rules/errors/e105-free-text-propagation.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e105-free-text-propagation.js +47 -0
- package/dist/runtime/analysis/rules/errors/e106-output-not-guaranteed.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e106-output-not-guaranteed.js +58 -0
- package/dist/runtime/analysis/rules/errors/e107-circular-dependency.d.ts +22 -0
- package/dist/runtime/analysis/rules/errors/e107-circular-dependency.js +84 -0
- package/dist/runtime/analysis/rules/errors/e108-implicit-user-input.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e108-implicit-user-input.js +94 -0
- package/dist/runtime/analysis/rules/errors/e109-non-serializable.d.ts +25 -0
- package/dist/runtime/analysis/rules/errors/e109-non-serializable.js +44 -0
- package/dist/runtime/analysis/rules/errors/e110-tool-ambiguity.d.ts +25 -0
- package/dist/runtime/analysis/rules/errors/e110-tool-ambiguity.js +73 -0
- package/dist/runtime/analysis/rules/errors/e200-input-validation-failed.d.ts +57 -0
- package/dist/runtime/analysis/rules/errors/e200-input-validation-failed.js +71 -0
- package/dist/runtime/analysis/rules/errors/e300-output-validation-failed.d.ts +43 -0
- package/dist/runtime/analysis/rules/errors/e300-output-validation-failed.js +44 -0
- package/dist/runtime/analysis/rules/errors/e301-output-explosion.d.ts +39 -0
- package/dist/runtime/analysis/rules/errors/e301-output-explosion.js +36 -0
- package/dist/runtime/analysis/rules/errors/e400-tool-execution-failed.d.ts +38 -0
- package/dist/runtime/analysis/rules/errors/e400-tool-execution-failed.js +37 -0
- package/dist/runtime/analysis/rules/errors/e403-unbounded-execution.d.ts +44 -0
- package/dist/runtime/analysis/rules/errors/e403-unbounded-execution.js +66 -0
- package/dist/runtime/analysis/rules/errors/e500-side-effect-detected.d.ts +39 -0
- package/dist/runtime/analysis/rules/errors/e500-side-effect-detected.js +40 -0
- package/dist/runtime/analysis/rules/errors/e501-hidden-dependency.d.ts +47 -0
- package/dist/runtime/analysis/rules/errors/e501-hidden-dependency.js +46 -0
- package/dist/runtime/analysis/rules/errors/e600-unexpected-test-result.d.ts +65 -0
- package/dist/runtime/analysis/rules/errors/e600-unexpected-test-result.js +109 -0
- package/dist/runtime/analysis/rules/index.d.ts +18 -0
- package/dist/runtime/analysis/rules/index.js +94 -0
- package/dist/runtime/analysis/rules/warnings/w001-implicit-dependency.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w001-implicit-dependency.js +39 -0
- package/dist/runtime/analysis/rules/warnings/w002-free-text-without-normalization.d.ts +24 -0
- package/dist/runtime/analysis/rules/warnings/w002-free-text-without-normalization.js +40 -0
- package/dist/runtime/analysis/rules/warnings/w003-missing-examples.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w003-missing-examples.js +84 -0
- package/dist/runtime/analysis/rules/warnings/w004-overloaded-responsibility.d.ts +23 -0
- package/dist/runtime/analysis/rules/warnings/w004-overloaded-responsibility.js +96 -0
- package/dist/runtime/analysis/rules/warnings/w005-generic-description.d.ts +53 -0
- package/dist/runtime/analysis/rules/warnings/w005-generic-description.js +108 -0
- package/dist/runtime/analysis/rules/warnings/w006-optional-as-required.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w006-optional-as-required.js +44 -0
- package/dist/runtime/analysis/rules/warnings/w007-broad-output-schema.d.ts +23 -0
- package/dist/runtime/analysis/rules/warnings/w007-broad-output-schema.js +37 -0
- package/dist/runtime/analysis/rules/warnings/w008-multiple-entry-points.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w008-multiple-entry-points.js +97 -0
- package/dist/runtime/analysis/rules/warnings/w009-hidden-side-effects.d.ts +23 -0
- package/dist/runtime/analysis/rules/warnings/w009-hidden-side-effects.js +88 -0
- package/dist/runtime/analysis/rules/warnings/w010-output-not-reusable.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w010-output-not-reusable.js +81 -0
- package/dist/runtime/analysis/rules/warnings/w021-weak-schema.d.ts +40 -0
- package/dist/runtime/analysis/rules/warnings/w021-weak-schema.js +32 -0
- package/dist/runtime/analysis/rules/warnings/w022-high-entropy-output.d.ts +39 -0
- package/dist/runtime/analysis/rules/warnings/w022-high-entropy-output.js +36 -0
- package/dist/runtime/analysis/rules/warnings/w023-unstable-defaults.d.ts +38 -0
- package/dist/runtime/analysis/rules/warnings/w023-unstable-defaults.js +36 -0
- package/dist/runtime/analysis/rules/warnings/w100-implicit-dependency.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w100-implicit-dependency.js +89 -0
- package/dist/runtime/analysis/rules/warnings/w101-free-text-without-normalization.d.ts +24 -0
- package/dist/runtime/analysis/rules/warnings/w101-free-text-without-normalization.js +40 -0
- package/dist/runtime/analysis/rules/warnings/w102-missing-examples.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w102-missing-examples.js +76 -0
- package/dist/runtime/analysis/rules/warnings/w103-overloaded-responsibility.d.ts +23 -0
- package/dist/runtime/analysis/rules/warnings/w103-overloaded-responsibility.js +91 -0
- package/dist/runtime/analysis/rules/warnings/w104-generic-description.d.ts +53 -0
- package/dist/runtime/analysis/rules/warnings/w104-generic-description.js +108 -0
- package/dist/runtime/analysis/rules/warnings/w105-optional-as-required.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w105-optional-as-required.js +45 -0
- package/dist/runtime/analysis/rules/warnings/w106-broad-output-schema.d.ts +23 -0
- package/dist/runtime/analysis/rules/warnings/w106-broad-output-schema.js +37 -0
- package/dist/runtime/analysis/rules/warnings/w107-multiple-entry-points.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w107-multiple-entry-points.js +97 -0
- package/dist/runtime/analysis/rules/warnings/w108-hidden-side-effects.d.ts +23 -0
- package/dist/runtime/analysis/rules/warnings/w108-hidden-side-effects.js +94 -0
- package/dist/runtime/analysis/rules/warnings/w109-output-not-reusable.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w109-output-not-reusable.js +63 -0
- package/dist/runtime/analysis/rules/warnings/w110-weak-schema.d.ts +40 -0
- package/dist/runtime/analysis/rules/warnings/w110-weak-schema.js +32 -0
- package/dist/runtime/analysis/rules/warnings/w300-high-entropy-output.d.ts +39 -0
- package/dist/runtime/analysis/rules/warnings/w300-high-entropy-output.js +47 -0
- package/dist/runtime/analysis/rules/warnings/w301-unstable-defaults.d.ts +38 -0
- package/dist/runtime/analysis/rules/warnings/w301-unstable-defaults.js +36 -0
- package/dist/runtime/analysis/strict-mode.d.ts +21 -0
- package/dist/runtime/analysis/strict-mode.js +44 -0
- package/dist/runtime/analysis/types.d.ts +133 -0
- package/dist/runtime/analysis/types.js +6 -0
- package/dist/runtime/analysis/utils.d.ts +19 -0
- package/dist/runtime/analysis/utils.js +21 -0
- package/dist/runtime/dev/data-manager.d.ts +55 -0
- package/dist/runtime/dev/data-manager.js +87 -0
- package/dist/runtime/dev/event-mapper.d.ts +100 -0
- package/dist/runtime/dev/event-mapper.js +400 -0
- package/dist/runtime/dev/formatter.d.ts +94 -0
- package/dist/runtime/dev/formatter.js +236 -0
- package/dist/runtime/dev/index.d.ts +9 -0
- package/dist/runtime/dev/index.js +9 -0
- package/dist/runtime/dev/repl.d.ts +114 -0
- package/dist/runtime/dev/repl.js +310 -0
- package/dist/runtime/dev/session.d.ts +86 -0
- package/dist/runtime/dev/session.js +447 -0
- package/dist/runtime/dev/stack-trace.d.ts +77 -0
- package/dist/runtime/dev/stack-trace.js +286 -0
- package/dist/runtime/dev/types.d.ts +54 -0
- package/dist/runtime/dev/types.js +5 -0
- package/dist/runtime/llm/claude.d.ts +27 -0
- package/dist/runtime/llm/claude.js +150 -0
- package/dist/runtime/llm/factory.d.ts +30 -0
- package/dist/runtime/llm/factory.js +78 -0
- package/dist/runtime/llm/index.d.ts +10 -0
- package/dist/runtime/llm/index.js +10 -0
- package/dist/runtime/llm/ollama.d.ts +45 -0
- package/dist/runtime/llm/ollama.js +449 -0
- package/dist/runtime/llm/openai.d.ts +27 -0
- package/dist/runtime/llm/openai.js +170 -0
- package/dist/runtime/llm/provider.d.ts +32 -0
- package/dist/runtime/llm/provider.js +6 -0
- package/dist/runtime/llm/types.d.ts +55 -0
- package/dist/runtime/llm/types.js +6 -0
- package/dist/runtime/mcp/client/base.d.ts +40 -0
- package/dist/runtime/mcp/client/base.js +157 -0
- package/dist/runtime/mcp/client/manager.d.ts +91 -0
- package/dist/runtime/mcp/client/manager.js +248 -0
- package/dist/runtime/mcp/client/process.d.ts +31 -0
- package/dist/runtime/mcp/client/process.js +82 -0
- package/dist/runtime/mcp/connection.d.ts +63 -0
- package/dist/runtime/mcp/connection.js +449 -0
- package/dist/runtime/mcp/index.d.ts +9 -0
- package/dist/runtime/mcp/index.js +9 -0
- package/dist/runtime/mcp/list.d.ts +50 -0
- package/dist/runtime/mcp/list.js +65 -0
- package/dist/runtime/mcp/stdio-transport.d.ts +23 -0
- package/dist/runtime/mcp/stdio-transport.js +71 -0
- package/dist/runtime/mcp/types.d.ts +85 -0
- package/dist/runtime/mcp/types.js +6 -0
- package/dist/runtime/sandbox/executor.d.ts +102 -0
- package/dist/runtime/sandbox/executor.js +537 -0
- package/dist/runtime/sandbox/index.d.ts +9 -0
- package/dist/runtime/sandbox/index.js +9 -0
- package/dist/runtime/sandbox/io-monitor.d.ts +78 -0
- package/dist/runtime/sandbox/io-monitor.js +98 -0
- package/dist/runtime/sandbox/time-parser.d.ts +19 -0
- package/dist/runtime/sandbox/time-parser.js +67 -0
- package/dist/runtime/sandbox/types.d.ts +58 -0
- package/dist/runtime/sandbox/types.js +23 -0
- package/dist/runtime/test/behavior-observer.d.ts +61 -0
- package/dist/runtime/test/behavior-observer.js +140 -0
- package/dist/runtime/test/contract-loader.d.ts +41 -0
- package/dist/runtime/test/contract-loader.js +158 -0
- package/dist/runtime/test/contract-schema.d.ts +46 -0
- package/dist/runtime/test/contract-schema.js +107 -0
- package/dist/runtime/test/contract-types.d.ts +106 -0
- package/dist/runtime/test/contract-types.js +6 -0
- package/dist/runtime/test/dependency-tracker.d.ts +66 -0
- package/dist/runtime/test/dependency-tracker.js +80 -0
- package/dist/runtime/test/formatters.d.ts +18 -0
- package/dist/runtime/test/formatters.js +172 -0
- package/dist/runtime/test/index.d.ts +12 -0
- package/dist/runtime/test/index.js +13 -0
- package/dist/runtime/test/input-generator.d.ts +33 -0
- package/dist/runtime/test/input-generator.js +498 -0
- package/dist/runtime/test/mcp-root-detector.d.ts +31 -0
- package/dist/runtime/test/mcp-root-detector.js +105 -0
- package/dist/runtime/test/orchestrator.d.ts +131 -0
- package/dist/runtime/test/orchestrator.js +738 -0
- package/dist/runtime/test/output-validator.d.ts +44 -0
- package/dist/runtime/test/output-validator.js +262 -0
- package/dist/runtime/test/retry-tester.d.ts +44 -0
- package/dist/runtime/test/retry-tester.js +103 -0
- package/dist/runtime/test/runner.d.ts +28 -0
- package/dist/runtime/test/runner.js +55 -0
- package/dist/runtime/test/synthetic-input-generator.d.ts +11 -0
- package/dist/runtime/test/synthetic-input-generator.js +154 -0
- package/dist/runtime/test/test-runner.d.ts +28 -0
- package/dist/runtime/test/test-runner.js +55 -0
- package/dist/types/factories.d.ts +16 -0
- package/dist/types/factories.js +43 -0
- package/dist/types/ids.d.ts +16 -0
- package/dist/types/ids.js +2 -0
- package/dist/types/opaque.d.ts +4 -0
- package/dist/types/opaque.js +2 -0
- package/dist/utils/errors.d.ts +92 -0
- package/dist/utils/errors.js +97 -0
- package/dist/utils/gitignore.d.ts +11 -0
- package/dist/utils/gitignore.js +59 -0
- package/dist/utils/json-file-saver.d.ts +17 -0
- package/dist/utils/json-file-saver.js +81 -0
- package/dist/utils/json-formatter.d.ts +63 -0
- package/dist/utils/json-formatter.js +344 -0
- package/dist/utils/logger.d.ts +184 -0
- package/dist/utils/logger.js +330 -0
- package/dist/utils/package-manager.d.ts +30 -0
- package/dist/utils/package-manager.js +157 -0
- package/dist/utils/version-checker.d.ts +47 -0
- package/dist/utils/version-checker.js +167 -0
- package/dist/utils/version-display.d.ts +10 -0
- package/dist/utils/version-display.js +20 -0
- package/package.json +106 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama (local) LLM provider implementation.
|
|
3
|
+
* Supports both Ollama SDK (automatic) and local command execution.
|
|
4
|
+
*/
|
|
5
|
+
import type { LLMProvider } from './provider.js';
|
|
6
|
+
import type { LLMRequest, LLMResponse } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Ollama provider implementation.
|
|
9
|
+
* Uses Ollama SDK to communicate with local Ollama instance.
|
|
10
|
+
* Automatically handles service startup and model downloading if needed.
|
|
11
|
+
*/
|
|
12
|
+
export declare class OllamaProvider implements LLMProvider {
|
|
13
|
+
private client;
|
|
14
|
+
private modelName;
|
|
15
|
+
private baseUrl;
|
|
16
|
+
constructor(modelName: string, baseUrl?: string);
|
|
17
|
+
getName(): string;
|
|
18
|
+
getModelName(): string;
|
|
19
|
+
supportsToolCalls(): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Ensure Ollama service is running, start it automatically if needed.
|
|
22
|
+
*/
|
|
23
|
+
private ensureOllamaRunning;
|
|
24
|
+
/**
|
|
25
|
+
* Check if model exists, download if it doesn't.
|
|
26
|
+
* Uses official Ollama API: https://github.com/ollama/ollama-js
|
|
27
|
+
*/
|
|
28
|
+
private ensureModelExists;
|
|
29
|
+
chat(request: LLMRequest): Promise<LLMResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* Check if Ollama is running.
|
|
32
|
+
* @param baseUrl - Base URL for Ollama API
|
|
33
|
+
* @returns true if Ollama is accessible
|
|
34
|
+
*/
|
|
35
|
+
static checkConnection(baseUrl?: string): Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* Create Ollama provider from config.
|
|
38
|
+
* @param modelNameEnvVar - Environment variable name for model name, or direct model name
|
|
39
|
+
* @param projectRoot - Project root directory
|
|
40
|
+
* @param baseUrl - Optional base URL for Ollama (defaults to http://localhost:11434)
|
|
41
|
+
* @returns Ollama provider instance
|
|
42
|
+
*/
|
|
43
|
+
static fromConfig(modelNameEnvVar: string, projectRoot?: string, baseUrl?: string): OllamaProvider;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=ollama.d.ts.map
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama (local) LLM provider implementation.
|
|
3
|
+
* Supports both Ollama SDK (automatic) and local command execution.
|
|
4
|
+
*/
|
|
5
|
+
import { Ollama } from 'ollama';
|
|
6
|
+
import * as childProcess from 'child_process';
|
|
7
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
8
|
+
import { ConfigurationError } from '../../utils/errors.js';
|
|
9
|
+
import { logger, log } from '../../utils/logger.js';
|
|
10
|
+
import { checkCommandExists, checkEnvVar } from '../../config/env-checker.js';
|
|
11
|
+
/**
|
|
12
|
+
* Static process manager for Ollama service.
|
|
13
|
+
* Ensures only one Ollama process is spawned per application instance.
|
|
14
|
+
*/
|
|
15
|
+
class OllamaProcessManager {
|
|
16
|
+
static ollamaProcess = null;
|
|
17
|
+
static isStarting = false;
|
|
18
|
+
/**
|
|
19
|
+
* Start Ollama service if not already running.
|
|
20
|
+
*/
|
|
21
|
+
static async ensureRunning(baseUrl = 'http://localhost:11434') {
|
|
22
|
+
// Check if already running
|
|
23
|
+
const client = new Ollama({ host: baseUrl });
|
|
24
|
+
try {
|
|
25
|
+
await client.list();
|
|
26
|
+
return; // Already running
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Not running, continue to start it
|
|
30
|
+
}
|
|
31
|
+
// Check if Ollama is installed
|
|
32
|
+
if (!checkCommandExists('ollama')) {
|
|
33
|
+
throw new ConfigurationError(`Ollama is not installed on your system.\n` +
|
|
34
|
+
`\n` +
|
|
35
|
+
`To install Ollama:\n` +
|
|
36
|
+
` 1. Visit https://ollama.ai and download for your platform\n` +
|
|
37
|
+
` 2. Install Ollama\n` +
|
|
38
|
+
` 3. Run this command again\n` +
|
|
39
|
+
`\n` +
|
|
40
|
+
`Note: We cannot automatically install Ollama as it requires system-level permissions.`);
|
|
41
|
+
}
|
|
42
|
+
// Prevent multiple simultaneous start attempts
|
|
43
|
+
if (this.isStarting) {
|
|
44
|
+
// Wait for the other start attempt to complete
|
|
45
|
+
let retries = 30; // Wait up to 30 seconds
|
|
46
|
+
while (this.isStarting && retries > 0) {
|
|
47
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
48
|
+
try {
|
|
49
|
+
await client.list();
|
|
50
|
+
return; // Started by another attempt
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
retries--;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (retries === 0) {
|
|
57
|
+
throw new ConfigurationError('Timeout waiting for Ollama service to start');
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
this.isStarting = true;
|
|
62
|
+
try {
|
|
63
|
+
log.info('🚀 Starting Ollama service...');
|
|
64
|
+
// Spawn Ollama serve process
|
|
65
|
+
this.ollamaProcess = childProcess.spawn('ollama', ['serve'], {
|
|
66
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
67
|
+
detached: false, // Keep attached so we can clean it up
|
|
68
|
+
});
|
|
69
|
+
// Set up cleanup on exit
|
|
70
|
+
const cleanup = () => {
|
|
71
|
+
if (this.ollamaProcess) {
|
|
72
|
+
try {
|
|
73
|
+
this.ollamaProcess.kill();
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Ignore errors during cleanup
|
|
77
|
+
}
|
|
78
|
+
this.ollamaProcess = null;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
process.once('exit', cleanup);
|
|
82
|
+
process.once('SIGINT', cleanup);
|
|
83
|
+
process.once('SIGTERM', cleanup);
|
|
84
|
+
// Capture output (but don't spam console)
|
|
85
|
+
this.ollamaProcess.stdout?.on('data', () => {
|
|
86
|
+
// Ollama serve outputs are usually not needed
|
|
87
|
+
});
|
|
88
|
+
this.ollamaProcess.stderr?.on('data', (data) => {
|
|
89
|
+
const message = data.toString().trim();
|
|
90
|
+
// Only log errors, not normal startup messages
|
|
91
|
+
if (message && /error|fatal|critical/i.test(message)) {
|
|
92
|
+
logger.warn(`Ollama: ${message}`);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
// Handle process errors
|
|
96
|
+
this.ollamaProcess.on('error', (error) => {
|
|
97
|
+
logger.error('Failed to start Ollama service', error);
|
|
98
|
+
this.ollamaProcess = null;
|
|
99
|
+
this.isStarting = false;
|
|
100
|
+
throw new ConfigurationError(`Failed to start Ollama service: ${error.message}`);
|
|
101
|
+
});
|
|
102
|
+
// Wait for Ollama to be ready (poll with retries)
|
|
103
|
+
const maxRetries = 30; // 30 seconds max
|
|
104
|
+
const retryDelay = 1000; // 1 second between retries
|
|
105
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
106
|
+
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
107
|
+
try {
|
|
108
|
+
await client.list();
|
|
109
|
+
log.success('✅ Ollama service is running');
|
|
110
|
+
log.blank();
|
|
111
|
+
this.isStarting = false;
|
|
112
|
+
return; // Success!
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Not ready yet, continue waiting
|
|
116
|
+
if (i === maxRetries - 1) {
|
|
117
|
+
// Last retry failed
|
|
118
|
+
if (this.ollamaProcess) {
|
|
119
|
+
this.ollamaProcess.kill();
|
|
120
|
+
this.ollamaProcess = null;
|
|
121
|
+
}
|
|
122
|
+
this.isStarting = false;
|
|
123
|
+
throw new ConfigurationError('Ollama service failed to start within 30 seconds. ' +
|
|
124
|
+
'Please check if Ollama is installed correctly.');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
this.isStarting = false;
|
|
131
|
+
if (error instanceof ConfigurationError) {
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
throw new ConfigurationError(`Failed to start Ollama service: ${error instanceof Error ? error.message : String(error)}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Stop the Ollama service if we started it.
|
|
139
|
+
*/
|
|
140
|
+
static stop() {
|
|
141
|
+
if (this.ollamaProcess) {
|
|
142
|
+
try {
|
|
143
|
+
this.ollamaProcess.kill();
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// Ignore errors
|
|
147
|
+
}
|
|
148
|
+
this.ollamaProcess = null;
|
|
149
|
+
}
|
|
150
|
+
this.isStarting = false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Ollama provider implementation.
|
|
155
|
+
* Uses Ollama SDK to communicate with local Ollama instance.
|
|
156
|
+
* Automatically handles service startup and model downloading if needed.
|
|
157
|
+
*/
|
|
158
|
+
export class OllamaProvider {
|
|
159
|
+
client;
|
|
160
|
+
modelName;
|
|
161
|
+
baseUrl;
|
|
162
|
+
constructor(modelName, baseUrl = 'http://localhost:11434') {
|
|
163
|
+
if (!modelName) {
|
|
164
|
+
throw new ConfigurationError('Ollama model name is required');
|
|
165
|
+
}
|
|
166
|
+
this.modelName = modelName;
|
|
167
|
+
this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
|
|
168
|
+
this.client = new Ollama({
|
|
169
|
+
host: this.baseUrl,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
getName() {
|
|
173
|
+
return 'Ollama';
|
|
174
|
+
}
|
|
175
|
+
getModelName() {
|
|
176
|
+
return this.modelName;
|
|
177
|
+
}
|
|
178
|
+
supportsToolCalls() {
|
|
179
|
+
// Ollama supports function calling/tools in newer models
|
|
180
|
+
// Most modern models (llama3.1+, mistral, etc.) support tools
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Ensure Ollama service is running, start it automatically if needed.
|
|
185
|
+
*/
|
|
186
|
+
async ensureOllamaRunning() {
|
|
187
|
+
try {
|
|
188
|
+
// Try to connect first
|
|
189
|
+
await this.client.list();
|
|
190
|
+
return; // Already running
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
// Not running, try to start it automatically
|
|
194
|
+
await OllamaProcessManager.ensureRunning(this.baseUrl);
|
|
195
|
+
// Verify it's now running
|
|
196
|
+
try {
|
|
197
|
+
await this.client.list();
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
201
|
+
throw new ConfigurationError(`Failed to connect to Ollama at ${this.baseUrl} after starting service: ${errorMessage}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Check if model exists, download if it doesn't.
|
|
207
|
+
* Uses official Ollama API: https://github.com/ollama/ollama-js
|
|
208
|
+
*/
|
|
209
|
+
async ensureModelExists() {
|
|
210
|
+
try {
|
|
211
|
+
// Check if model exists using list() API
|
|
212
|
+
const modelsResponse = await this.client.list();
|
|
213
|
+
const modelExists = modelsResponse.models?.some((m) => m.name === this.modelName || m.name.startsWith(`${this.modelName}:`)) ?? false;
|
|
214
|
+
if (!modelExists) {
|
|
215
|
+
logger.info(`Model ${this.modelName} not found. Downloading...`);
|
|
216
|
+
log.blank();
|
|
217
|
+
log.info(`📥 Downloading model: ${this.modelName}`);
|
|
218
|
+
log.plain('This may take a few minutes depending on your internet connection...');
|
|
219
|
+
log.blank();
|
|
220
|
+
// Pull the model using official API with streaming for progress
|
|
221
|
+
const stream = await this.client.pull({
|
|
222
|
+
model: this.modelName,
|
|
223
|
+
stream: true,
|
|
224
|
+
});
|
|
225
|
+
// Show download progress according to ollama-js API
|
|
226
|
+
// Stream chunks have: status, completed, total, etc.
|
|
227
|
+
let lastPercent = 0;
|
|
228
|
+
for await (const chunk of stream) {
|
|
229
|
+
// Handle progress updates
|
|
230
|
+
if (chunk.completed !== undefined &&
|
|
231
|
+
chunk.total !== undefined &&
|
|
232
|
+
chunk.total > 0) {
|
|
233
|
+
const percent = Math.round((chunk.completed / chunk.total) * 100);
|
|
234
|
+
if (percent !== lastPercent) {
|
|
235
|
+
process.stdout.write(`\r📥 Downloading: ${percent}%`);
|
|
236
|
+
lastPercent = percent;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Show status messages
|
|
240
|
+
if (chunk.status) {
|
|
241
|
+
process.stdout.write(`\r📥 ${chunk.status}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
log.blank();
|
|
245
|
+
log.success('✅ Model downloaded successfully!');
|
|
246
|
+
log.blank();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
251
|
+
throw new ConfigurationError(`Failed to ensure model ${this.modelName} is available: ${errorMessage}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
async chat(request) {
|
|
255
|
+
try {
|
|
256
|
+
// Ensure Ollama is running
|
|
257
|
+
await this.ensureOllamaRunning();
|
|
258
|
+
// Ensure model exists (download if needed)
|
|
259
|
+
await this.ensureModelExists();
|
|
260
|
+
// Build messages for Ollama
|
|
261
|
+
const messages = request.messages.map(msg => ({
|
|
262
|
+
role: msg.role,
|
|
263
|
+
content: msg.content,
|
|
264
|
+
}));
|
|
265
|
+
// Add system prompt if provided
|
|
266
|
+
if (request.systemPrompt) {
|
|
267
|
+
messages.unshift({
|
|
268
|
+
role: 'system',
|
|
269
|
+
content: request.systemPrompt,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
// Convert tools to Ollama format if provided
|
|
273
|
+
// Ollama uses a 'tools' array with function definitions
|
|
274
|
+
const tools = request.tools?.map(tool => {
|
|
275
|
+
// Ollama expects tools in a specific format
|
|
276
|
+
// Format: { type: 'function', function: { name, description, parameters } }
|
|
277
|
+
const inputSchema = tool.inputSchema;
|
|
278
|
+
// Convert properties to the format Ollama expects
|
|
279
|
+
const properties = {};
|
|
280
|
+
if (inputSchema.properties) {
|
|
281
|
+
for (const [key, value] of Object.entries(inputSchema.properties)) {
|
|
282
|
+
if (value &&
|
|
283
|
+
typeof value === 'object' &&
|
|
284
|
+
('type' in value || 'description' in value)) {
|
|
285
|
+
properties[key] = value;
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
// Default structure if not properly formatted
|
|
289
|
+
const valueStr = typeof value === 'string'
|
|
290
|
+
? value
|
|
291
|
+
: value && typeof value === 'object'
|
|
292
|
+
? JSON.stringify(value)
|
|
293
|
+
: String(value);
|
|
294
|
+
properties[key] = {
|
|
295
|
+
type: 'string',
|
|
296
|
+
description: valueStr,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
type: 'function',
|
|
303
|
+
function: {
|
|
304
|
+
name: tool.name,
|
|
305
|
+
description: tool.description,
|
|
306
|
+
parameters: {
|
|
307
|
+
type: 'object',
|
|
308
|
+
properties,
|
|
309
|
+
required: inputSchema.required || [],
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
};
|
|
313
|
+
});
|
|
314
|
+
// Call Ollama API according to official API: https://github.com/ollama/ollama-js
|
|
315
|
+
const chatRequest = {
|
|
316
|
+
model: this.modelName,
|
|
317
|
+
messages,
|
|
318
|
+
stream: false, // We want a complete response, not a stream
|
|
319
|
+
options: {
|
|
320
|
+
temperature: request.temperature ?? 0.7,
|
|
321
|
+
num_predict: request.maxTokens,
|
|
322
|
+
},
|
|
323
|
+
};
|
|
324
|
+
// Add tools if available
|
|
325
|
+
if (tools && tools.length > 0) {
|
|
326
|
+
chatRequest.tools = tools;
|
|
327
|
+
}
|
|
328
|
+
const response = await this.client.chat(chatRequest);
|
|
329
|
+
// Response structure according to ollama-js API:
|
|
330
|
+
// { message: { role: string, content: string, tool_calls?: [...] }, done: boolean, ... }
|
|
331
|
+
const content = response.message?.content || '';
|
|
332
|
+
// Extract tool calls from response
|
|
333
|
+
// Ollama returns tool_calls in the message if the model supports it
|
|
334
|
+
const toolCalls = [];
|
|
335
|
+
if (response.message &&
|
|
336
|
+
'tool_calls' in response.message &&
|
|
337
|
+
response.message.tool_calls) {
|
|
338
|
+
const toolCallsArray = response.message.tool_calls;
|
|
339
|
+
for (const toolCall of toolCallsArray) {
|
|
340
|
+
if (toolCall.function) {
|
|
341
|
+
try {
|
|
342
|
+
let args;
|
|
343
|
+
if (typeof toolCall.function.arguments === 'string') {
|
|
344
|
+
args = JSON.parse(toolCall.function.arguments);
|
|
345
|
+
}
|
|
346
|
+
else if (toolCall.function.arguments &&
|
|
347
|
+
typeof toolCall.function.arguments === 'object' &&
|
|
348
|
+
!Array.isArray(toolCall.function.arguments)) {
|
|
349
|
+
args = toolCall.function.arguments;
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
args = {};
|
|
353
|
+
}
|
|
354
|
+
toolCalls.push({
|
|
355
|
+
id: toolCall.id || uuidv4(),
|
|
356
|
+
name: toolCall.function.name,
|
|
357
|
+
arguments: args,
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
// If parsing fails, use empty object
|
|
362
|
+
toolCalls.push({
|
|
363
|
+
id: toolCall.id || uuidv4(),
|
|
364
|
+
name: toolCall.function.name,
|
|
365
|
+
arguments: {},
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
const finishReason = toolCalls.length > 0 ? 'tool_calls' : response.done ? 'stop' : 'length';
|
|
372
|
+
// Extract usage statistics if available
|
|
373
|
+
const evalCount = response.eval_count;
|
|
374
|
+
const promptEvalCount = response.prompt_eval_count;
|
|
375
|
+
return {
|
|
376
|
+
content,
|
|
377
|
+
finishReason,
|
|
378
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
379
|
+
usage: evalCount !== undefined && promptEvalCount !== undefined
|
|
380
|
+
? {
|
|
381
|
+
promptTokens: promptEvalCount,
|
|
382
|
+
completionTokens: evalCount,
|
|
383
|
+
totalTokens: promptEvalCount + evalCount,
|
|
384
|
+
}
|
|
385
|
+
: undefined,
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
catch (err) {
|
|
389
|
+
if (err instanceof ConfigurationError) {
|
|
390
|
+
throw err;
|
|
391
|
+
}
|
|
392
|
+
if (err instanceof Error) {
|
|
393
|
+
// Check if it's a connection error - try to start Ollama automatically
|
|
394
|
+
if (err.message.includes('fetch failed') ||
|
|
395
|
+
err.message.includes('ECONNREFUSED') ||
|
|
396
|
+
err.message.includes('ENOTFOUND')) {
|
|
397
|
+
try {
|
|
398
|
+
// Try to start Ollama automatically
|
|
399
|
+
await OllamaProcessManager.ensureRunning(this.baseUrl);
|
|
400
|
+
// Retry the request
|
|
401
|
+
return this.chat(request);
|
|
402
|
+
}
|
|
403
|
+
catch (startError) {
|
|
404
|
+
if (startError instanceof ConfigurationError) {
|
|
405
|
+
throw startError;
|
|
406
|
+
}
|
|
407
|
+
throw new ConfigurationError(`Cannot connect to Ollama at ${this.baseUrl}. ` +
|
|
408
|
+
`Failed to start service automatically: ${startError instanceof Error
|
|
409
|
+
? startError.message
|
|
410
|
+
: String(startError)}`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
throw new Error(`Ollama API error: ${err.message}`);
|
|
414
|
+
}
|
|
415
|
+
throw new Error('Unknown error from Ollama API');
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Check if Ollama is running.
|
|
420
|
+
* @param baseUrl - Base URL for Ollama API
|
|
421
|
+
* @returns true if Ollama is accessible
|
|
422
|
+
*/
|
|
423
|
+
static async checkConnection(baseUrl = 'http://localhost:11434') {
|
|
424
|
+
try {
|
|
425
|
+
const client = new Ollama({ host: baseUrl });
|
|
426
|
+
await client.list();
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
catch {
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Create Ollama provider from config.
|
|
435
|
+
* @param modelNameEnvVar - Environment variable name for model name, or direct model name
|
|
436
|
+
* @param projectRoot - Project root directory
|
|
437
|
+
* @param baseUrl - Optional base URL for Ollama (defaults to http://localhost:11434)
|
|
438
|
+
* @returns Ollama provider instance
|
|
439
|
+
*/
|
|
440
|
+
static fromConfig(modelNameEnvVar, projectRoot = process.cwd(), baseUrl) {
|
|
441
|
+
const modelNameCheck = checkEnvVar(modelNameEnvVar, projectRoot);
|
|
442
|
+
if (!modelNameCheck.isSet || !modelNameCheck.value) {
|
|
443
|
+
throw new ConfigurationError(modelNameCheck.errorMessage ||
|
|
444
|
+
`Ollama model name (${modelNameEnvVar}) is not set`);
|
|
445
|
+
}
|
|
446
|
+
return new OllamaProvider(modelNameCheck.value, baseUrl);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
//# sourceMappingURL=ollama.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI LLM provider implementation.
|
|
3
|
+
*/
|
|
4
|
+
import type { LLMProvider } from './provider.js';
|
|
5
|
+
import type { LLMRequest, LLMResponse } from './types.js';
|
|
6
|
+
import type { APIKey, ModelName } from '../../types/ids.js';
|
|
7
|
+
/**
|
|
8
|
+
* OpenAI provider implementation.
|
|
9
|
+
*/
|
|
10
|
+
export declare class OpenAIProvider implements LLMProvider {
|
|
11
|
+
private client;
|
|
12
|
+
private modelName;
|
|
13
|
+
constructor(apiKey: string, modelName: string);
|
|
14
|
+
getName(): string;
|
|
15
|
+
getModelName(): string;
|
|
16
|
+
supportsToolCalls(): boolean;
|
|
17
|
+
chat(request: LLMRequest): Promise<LLMResponse>;
|
|
18
|
+
/**
|
|
19
|
+
* Create OpenAI provider from config.
|
|
20
|
+
* @param apiKeyEnvVar - Environment variable name for API key
|
|
21
|
+
* @param modelNameEnvVar - Environment variable name for model name
|
|
22
|
+
* @param projectRoot - Project root directory
|
|
23
|
+
* @returns OpenAI provider instance
|
|
24
|
+
*/
|
|
25
|
+
static fromConfig(apiKeyEnvVar: APIKey | string, modelNameEnvVar: ModelName | string, projectRoot?: string): OpenAIProvider;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI LLM provider implementation.
|
|
3
|
+
*/
|
|
4
|
+
import OpenAI from 'openai';
|
|
5
|
+
import { checkEnvVar } from '../../config/env-checker.js';
|
|
6
|
+
import { ConfigurationError } from '../../utils/errors.js';
|
|
7
|
+
/**
|
|
8
|
+
* OpenAI provider implementation.
|
|
9
|
+
*/
|
|
10
|
+
export class OpenAIProvider {
|
|
11
|
+
client;
|
|
12
|
+
modelName;
|
|
13
|
+
constructor(apiKey, modelName) {
|
|
14
|
+
if (!apiKey) {
|
|
15
|
+
throw new ConfigurationError('OpenAI API key is required');
|
|
16
|
+
}
|
|
17
|
+
if (!modelName) {
|
|
18
|
+
throw new ConfigurationError('OpenAI model name is required');
|
|
19
|
+
}
|
|
20
|
+
this.client = new OpenAI({
|
|
21
|
+
apiKey,
|
|
22
|
+
});
|
|
23
|
+
this.modelName = modelName;
|
|
24
|
+
}
|
|
25
|
+
getName() {
|
|
26
|
+
return 'OpenAI';
|
|
27
|
+
}
|
|
28
|
+
getModelName() {
|
|
29
|
+
return this.modelName;
|
|
30
|
+
}
|
|
31
|
+
supportsToolCalls() {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
async chat(request) {
|
|
35
|
+
try {
|
|
36
|
+
// Convert tools to OpenAI function format
|
|
37
|
+
const functions = request.tools?.map(tool => {
|
|
38
|
+
const schema = tool.inputSchema;
|
|
39
|
+
// Check if schema is empty (no properties or empty properties object)
|
|
40
|
+
let isEmpty = true;
|
|
41
|
+
let schemaObj = null;
|
|
42
|
+
if (schema && typeof schema === 'object' && schema !== null) {
|
|
43
|
+
schemaObj = schema;
|
|
44
|
+
isEmpty =
|
|
45
|
+
schemaObj.type === 'object' &&
|
|
46
|
+
(!schemaObj.properties ||
|
|
47
|
+
(typeof schemaObj.properties === 'object' &&
|
|
48
|
+
schemaObj.properties !== null &&
|
|
49
|
+
Object.keys(schemaObj.properties).length === 0));
|
|
50
|
+
}
|
|
51
|
+
// For OpenAI, omit parameters if schema is empty to avoid validation errors
|
|
52
|
+
const functionDef = {
|
|
53
|
+
name: tool.name,
|
|
54
|
+
description: tool.description,
|
|
55
|
+
};
|
|
56
|
+
if (!isEmpty && schemaObj) {
|
|
57
|
+
functionDef.parameters = schemaObj;
|
|
58
|
+
}
|
|
59
|
+
return functionDef;
|
|
60
|
+
});
|
|
61
|
+
const messages = request.messages.map(msg => ({
|
|
62
|
+
role: msg.role,
|
|
63
|
+
content: msg.content,
|
|
64
|
+
}));
|
|
65
|
+
// Add system prompt if provided
|
|
66
|
+
if (request.systemPrompt) {
|
|
67
|
+
messages.unshift({
|
|
68
|
+
role: 'system',
|
|
69
|
+
content: request.systemPrompt,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const response = await this.client.chat.completions.create({
|
|
73
|
+
model: this.modelName,
|
|
74
|
+
messages,
|
|
75
|
+
functions,
|
|
76
|
+
temperature: request.temperature ?? 0.7,
|
|
77
|
+
max_tokens: request.maxTokens,
|
|
78
|
+
});
|
|
79
|
+
const choice = response.choices[0];
|
|
80
|
+
if (!choice) {
|
|
81
|
+
throw new Error('No response from OpenAI');
|
|
82
|
+
}
|
|
83
|
+
const content = choice.message.content || '';
|
|
84
|
+
const finishReason = choice.finish_reason;
|
|
85
|
+
// Extract tool calls if present
|
|
86
|
+
const toolCalls = [];
|
|
87
|
+
if (choice.message.function_call) {
|
|
88
|
+
const funcCall = choice.message.function_call;
|
|
89
|
+
try {
|
|
90
|
+
toolCalls.push({
|
|
91
|
+
id: funcCall.name || '',
|
|
92
|
+
name: funcCall.name || '',
|
|
93
|
+
arguments: JSON.parse(funcCall.arguments || '{}'),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// If parsing fails, use empty object
|
|
98
|
+
toolCalls.push({
|
|
99
|
+
id: funcCall.name || '',
|
|
100
|
+
name: funcCall.name || '',
|
|
101
|
+
arguments: {},
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Handle multiple function calls (newer API)
|
|
106
|
+
if (choice.message.tool_calls) {
|
|
107
|
+
for (const toolCall of choice.message.tool_calls) {
|
|
108
|
+
if (toolCall.type === 'function') {
|
|
109
|
+
try {
|
|
110
|
+
toolCalls.push({
|
|
111
|
+
id: toolCall.id,
|
|
112
|
+
name: toolCall.function.name || '',
|
|
113
|
+
arguments: JSON.parse(toolCall.function.arguments || '{}'),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// If parsing fails, use empty object
|
|
118
|
+
toolCalls.push({
|
|
119
|
+
id: toolCall.id,
|
|
120
|
+
name: toolCall.function.name || '',
|
|
121
|
+
arguments: {},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
content,
|
|
129
|
+
finishReason,
|
|
130
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
131
|
+
usage: response.usage
|
|
132
|
+
? {
|
|
133
|
+
promptTokens: response.usage.prompt_tokens,
|
|
134
|
+
completionTokens: response.usage.completion_tokens,
|
|
135
|
+
totalTokens: response.usage.total_tokens,
|
|
136
|
+
}
|
|
137
|
+
: undefined,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
if (error instanceof Error) {
|
|
142
|
+
throw new Error(`OpenAI API error: ${error.message}`);
|
|
143
|
+
}
|
|
144
|
+
throw new Error('Unknown error from OpenAI API');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Create OpenAI provider from config.
|
|
149
|
+
* @param apiKeyEnvVar - Environment variable name for API key
|
|
150
|
+
* @param modelNameEnvVar - Environment variable name for model name
|
|
151
|
+
* @param projectRoot - Project root directory
|
|
152
|
+
* @returns OpenAI provider instance
|
|
153
|
+
*/
|
|
154
|
+
static fromConfig(apiKeyEnvVar, modelNameEnvVar, projectRoot = process.cwd()) {
|
|
155
|
+
// Check API key
|
|
156
|
+
const apiKeyCheck = checkEnvVar(apiKeyEnvVar, projectRoot);
|
|
157
|
+
if (!apiKeyCheck.isSet || !apiKeyCheck.value) {
|
|
158
|
+
throw new ConfigurationError(apiKeyCheck.errorMessage ||
|
|
159
|
+
`OpenAI API key (${apiKeyEnvVar}) is not set`);
|
|
160
|
+
}
|
|
161
|
+
// Check model name
|
|
162
|
+
const modelNameCheck = checkEnvVar(modelNameEnvVar, projectRoot);
|
|
163
|
+
if (!modelNameCheck.isSet || !modelNameCheck.value) {
|
|
164
|
+
throw new ConfigurationError(modelNameCheck.errorMessage ||
|
|
165
|
+
`OpenAI model name (${modelNameEnvVar}) is not set`);
|
|
166
|
+
}
|
|
167
|
+
return new OpenAIProvider(apiKeyCheck.value, modelNameCheck.value);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=openai.js.map
|