@pencil-agent/nano-pencil 1.11.32 → 1.11.34
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/dist/cli.js +0 -0
- package/dist/core/config/settings-manager.d.ts +8 -0
- package/dist/core/config/settings-manager.js +16 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +2 -0
- package/dist/core/model/switcher.d.ts +2 -1
- package/dist/core/model/switcher.js +30 -7
- package/dist/core/model-registry.d.ts +14 -0
- package/dist/core/model-registry.js +64 -1
- package/dist/core/runtime/agent-session.d.ts +8 -0
- package/dist/core/runtime/agent-session.js +47 -8
- package/dist/modes/interactive/components/custom-editor.d.ts +4 -2
- package/dist/modes/interactive/components/custom-editor.js +33 -7
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +3 -1
- package/dist/modes/interactive/components/model-selector.js +58 -26
- package/dist/modes/interactive/interactive-mode.d.ts +47 -1
- package/dist/modes/interactive/interactive-mode.js +653 -46
- package/dist/nanopencil-defaults.d.ts +8 -2
- package/dist/nanopencil-defaults.js +61 -2
- package/dist/node_modules/zod/LICENSE +21 -0
- package/dist/node_modules/zod/README.md +208 -0
- package/dist/node_modules/zod/index.js +4 -0
- package/dist/node_modules/zod/locales/index.d.ts +1 -0
- package/dist/node_modules/zod/locales/index.js +1 -0
- package/dist/node_modules/zod/locales/package.json +6 -0
- package/dist/node_modules/zod/mini/index.d.ts +3 -0
- package/dist/node_modules/zod/mini/index.js +3 -0
- package/dist/node_modules/zod/mini/package.json +6 -0
- package/dist/node_modules/zod/package.json +135 -0
- package/dist/node_modules/zod/v3/ZodError.d.ts +164 -0
- package/dist/node_modules/zod/v3/ZodError.js +133 -0
- package/dist/node_modules/zod/v3/errors.d.ts +5 -0
- package/dist/node_modules/zod/v3/errors.js +9 -0
- package/dist/node_modules/zod/v3/external.d.ts +6 -0
- package/dist/node_modules/zod/v3/external.js +6 -0
- package/dist/node_modules/zod/v3/helpers/enumUtil.d.ts +8 -0
- package/dist/node_modules/zod/v3/helpers/enumUtil.js +1 -0
- package/dist/node_modules/zod/v3/helpers/errorUtil.d.ts +9 -0
- package/dist/node_modules/zod/v3/helpers/errorUtil.js +6 -0
- package/dist/node_modules/zod/v3/helpers/parseUtil.d.ts +78 -0
- package/dist/node_modules/zod/v3/helpers/parseUtil.js +109 -0
- package/dist/node_modules/zod/v3/helpers/partialUtil.d.ts +8 -0
- package/dist/node_modules/zod/v3/helpers/partialUtil.js +1 -0
- package/dist/node_modules/zod/v3/helpers/typeAliases.d.ts +2 -0
- package/dist/node_modules/zod/v3/helpers/typeAliases.js +1 -0
- package/dist/node_modules/zod/v3/helpers/util.d.ts +85 -0
- package/dist/node_modules/zod/v3/helpers/util.js +133 -0
- package/dist/node_modules/zod/v3/index.d.ts +4 -0
- package/dist/node_modules/zod/v3/index.js +4 -0
- package/dist/node_modules/zod/v3/locales/en.d.ts +3 -0
- package/dist/node_modules/zod/v3/locales/en.js +109 -0
- package/dist/node_modules/zod/v3/package.json +6 -0
- package/dist/node_modules/zod/v3/standard-schema.d.ts +102 -0
- package/dist/node_modules/zod/v3/standard-schema.js +1 -0
- package/dist/node_modules/zod/v3/types.d.ts +1034 -0
- package/dist/node_modules/zod/v3/types.js +3695 -0
- package/dist/node_modules/zod/v4/classic/checks.d.ts +1 -0
- package/dist/node_modules/zod/v4/classic/checks.js +1 -0
- package/dist/node_modules/zod/v4/classic/coerce.d.ts +17 -0
- package/dist/node_modules/zod/v4/classic/coerce.js +17 -0
- package/dist/node_modules/zod/v4/classic/compat.d.ts +50 -0
- package/dist/node_modules/zod/v4/classic/compat.js +31 -0
- package/dist/node_modules/zod/v4/classic/errors.d.ts +30 -0
- package/dist/node_modules/zod/v4/classic/errors.js +48 -0
- package/dist/node_modules/zod/v4/classic/external.d.ts +15 -0
- package/dist/node_modules/zod/v4/classic/external.js +20 -0
- package/dist/node_modules/zod/v4/classic/from-json-schema.d.ts +12 -0
- package/dist/node_modules/zod/v4/classic/from-json-schema.js +584 -0
- package/dist/node_modules/zod/v4/classic/index.d.ts +4 -0
- package/dist/node_modules/zod/v4/classic/index.js +4 -0
- package/dist/node_modules/zod/v4/classic/iso.d.ts +22 -0
- package/dist/node_modules/zod/v4/classic/iso.js +30 -0
- package/dist/node_modules/zod/v4/classic/package.json +6 -0
- package/dist/node_modules/zod/v4/classic/parse.d.ts +31 -0
- package/dist/node_modules/zod/v4/classic/parse.js +15 -0
- package/dist/node_modules/zod/v4/classic/schemas.d.ts +739 -0
- package/dist/node_modules/zod/v4/classic/schemas.js +1157 -0
- package/dist/node_modules/zod/v4/core/api.d.ts +304 -0
- package/dist/node_modules/zod/v4/core/api.js +1082 -0
- package/dist/node_modules/zod/v4/core/checks.d.ts +278 -0
- package/dist/node_modules/zod/v4/core/checks.js +575 -0
- package/dist/node_modules/zod/v4/core/core.d.ts +70 -0
- package/dist/node_modules/zod/v4/core/core.js +76 -0
- package/dist/node_modules/zod/v4/core/doc.d.ts +14 -0
- package/dist/node_modules/zod/v4/core/doc.js +35 -0
- package/dist/node_modules/zod/v4/core/errors.d.ts +220 -0
- package/dist/node_modules/zod/v4/core/errors.js +182 -0
- package/dist/node_modules/zod/v4/core/index.d.ts +16 -0
- package/dist/node_modules/zod/v4/core/index.js +16 -0
- package/dist/node_modules/zod/v4/core/json-schema-generator.d.ts +65 -0
- package/dist/node_modules/zod/v4/core/json-schema-generator.js +95 -0
- package/dist/node_modules/zod/v4/core/json-schema-processors.d.ts +49 -0
- package/dist/node_modules/zod/v4/core/json-schema-processors.js +605 -0
- package/dist/node_modules/zod/v4/core/json-schema.d.ts +88 -0
- package/dist/node_modules/zod/v4/core/json-schema.js +1 -0
- package/dist/node_modules/zod/v4/core/package.json +6 -0
- package/dist/node_modules/zod/v4/core/parse.d.ts +49 -0
- package/dist/node_modules/zod/v4/core/parse.js +93 -0
- package/dist/node_modules/zod/v4/core/regexes.d.ts +79 -0
- package/dist/node_modules/zod/v4/core/regexes.js +133 -0
- package/dist/node_modules/zod/v4/core/registries.d.ts +35 -0
- package/dist/node_modules/zod/v4/core/registries.js +51 -0
- package/dist/node_modules/zod/v4/core/schemas.d.ts +1146 -0
- package/dist/node_modules/zod/v4/core/schemas.js +2093 -0
- package/dist/node_modules/zod/v4/core/standard-schema.d.ts +126 -0
- package/dist/node_modules/zod/v4/core/standard-schema.js +1 -0
- package/dist/node_modules/zod/v4/core/to-json-schema.d.ts +114 -0
- package/dist/node_modules/zod/v4/core/to-json-schema.js +437 -0
- package/dist/node_modules/zod/v4/core/util.d.ts +199 -0
- package/dist/node_modules/zod/v4/core/util.js +651 -0
- package/dist/node_modules/zod/v4/core/versions.d.ts +5 -0
- package/dist/node_modules/zod/v4/core/versions.js +5 -0
- package/dist/node_modules/zod/v4/index.d.ts +3 -0
- package/dist/node_modules/zod/v4/index.js +3 -0
- package/dist/node_modules/zod/v4/locales/ar.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ar.js +106 -0
- package/dist/node_modules/zod/v4/locales/az.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/az.js +105 -0
- package/dist/node_modules/zod/v4/locales/be.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/be.js +156 -0
- package/dist/node_modules/zod/v4/locales/bg.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/bg.js +120 -0
- package/dist/node_modules/zod/v4/locales/ca.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ca.js +107 -0
- package/dist/node_modules/zod/v4/locales/cs.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/cs.js +111 -0
- package/dist/node_modules/zod/v4/locales/da.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/da.js +115 -0
- package/dist/node_modules/zod/v4/locales/de.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/de.js +108 -0
- package/dist/node_modules/zod/v4/locales/en.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/en.js +109 -0
- package/dist/node_modules/zod/v4/locales/eo.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/eo.js +109 -0
- package/dist/node_modules/zod/v4/locales/es.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/es.js +132 -0
- package/dist/node_modules/zod/v4/locales/fa.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/fa.js +114 -0
- package/dist/node_modules/zod/v4/locales/fi.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/fi.js +112 -0
- package/dist/node_modules/zod/v4/locales/fr-CA.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/fr-CA.js +107 -0
- package/dist/node_modules/zod/v4/locales/fr.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/fr.js +108 -0
- package/dist/node_modules/zod/v4/locales/he.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/he.js +214 -0
- package/dist/node_modules/zod/v4/locales/hu.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/hu.js +108 -0
- package/dist/node_modules/zod/v4/locales/hy.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/hy.js +147 -0
- package/dist/node_modules/zod/v4/locales/id.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/id.js +106 -0
- package/dist/node_modules/zod/v4/locales/index.d.ts +49 -0
- package/dist/node_modules/zod/v4/locales/index.js +49 -0
- package/dist/node_modules/zod/v4/locales/is.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/is.js +109 -0
- package/dist/node_modules/zod/v4/locales/it.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/it.js +108 -0
- package/dist/node_modules/zod/v4/locales/ja.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ja.js +107 -0
- package/dist/node_modules/zod/v4/locales/ka.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ka.js +112 -0
- package/dist/node_modules/zod/v4/locales/kh.d.ts +5 -0
- package/dist/node_modules/zod/v4/locales/kh.js +5 -0
- package/dist/node_modules/zod/v4/locales/km.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/km.js +110 -0
- package/dist/node_modules/zod/v4/locales/ko.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ko.js +111 -0
- package/dist/node_modules/zod/v4/locales/lt.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/lt.js +203 -0
- package/dist/node_modules/zod/v4/locales/mk.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/mk.js +109 -0
- package/dist/node_modules/zod/v4/locales/ms.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ms.js +107 -0
- package/dist/node_modules/zod/v4/locales/nl.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/nl.js +110 -0
- package/dist/node_modules/zod/v4/locales/no.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/no.js +108 -0
- package/dist/node_modules/zod/v4/locales/ota.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ota.js +109 -0
- package/dist/node_modules/zod/v4/locales/package.json +6 -0
- package/dist/node_modules/zod/v4/locales/pl.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/pl.js +109 -0
- package/dist/node_modules/zod/v4/locales/ps.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ps.js +114 -0
- package/dist/node_modules/zod/v4/locales/pt.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/pt.js +108 -0
- package/dist/node_modules/zod/v4/locales/ru.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ru.js +156 -0
- package/dist/node_modules/zod/v4/locales/sl.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/sl.js +109 -0
- package/dist/node_modules/zod/v4/locales/sv.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/sv.js +110 -0
- package/dist/node_modules/zod/v4/locales/ta.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ta.js +110 -0
- package/dist/node_modules/zod/v4/locales/th.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/th.js +110 -0
- package/dist/node_modules/zod/v4/locales/tr.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/tr.js +105 -0
- package/dist/node_modules/zod/v4/locales/ua.d.ts +5 -0
- package/dist/node_modules/zod/v4/locales/ua.js +5 -0
- package/dist/node_modules/zod/v4/locales/uk.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/uk.js +108 -0
- package/dist/node_modules/zod/v4/locales/ur.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/ur.js +110 -0
- package/dist/node_modules/zod/v4/locales/uz.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/uz.js +109 -0
- package/dist/node_modules/zod/v4/locales/vi.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/vi.js +108 -0
- package/dist/node_modules/zod/v4/locales/yo.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/yo.js +107 -0
- package/dist/node_modules/zod/v4/locales/zh-CN.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/zh-CN.js +109 -0
- package/dist/node_modules/zod/v4/locales/zh-TW.d.ts +4 -0
- package/dist/node_modules/zod/v4/locales/zh-TW.js +107 -0
- package/dist/node_modules/zod/v4/mini/checks.d.ts +1 -0
- package/dist/node_modules/zod/v4/mini/checks.js +1 -0
- package/dist/node_modules/zod/v4/mini/coerce.d.ts +7 -0
- package/dist/node_modules/zod/v4/mini/coerce.js +22 -0
- package/dist/node_modules/zod/v4/mini/external.d.ts +12 -0
- package/dist/node_modules/zod/v4/mini/external.js +14 -0
- package/dist/node_modules/zod/v4/mini/index.d.ts +3 -0
- package/dist/node_modules/zod/v4/mini/index.js +3 -0
- package/dist/node_modules/zod/v4/mini/iso.d.ts +22 -0
- package/dist/node_modules/zod/v4/mini/iso.js +34 -0
- package/dist/node_modules/zod/v4/mini/package.json +6 -0
- package/dist/node_modules/zod/v4/mini/parse.d.ts +1 -0
- package/dist/node_modules/zod/v4/mini/parse.js +1 -0
- package/dist/node_modules/zod/v4/mini/schemas.d.ts +427 -0
- package/dist/node_modules/zod/v4/mini/schemas.js +925 -0
- package/dist/node_modules/zod/v4/package.json +6 -0
- package/dist/node_modules/zod/v4-mini/index.d.ts +3 -0
- package/dist/node_modules/zod/v4-mini/index.js +3 -0
- package/dist/node_modules/zod/v4-mini/package.json +6 -0
- package/docs/debug-logging.md +148 -0
- package/node_modules/@pencil-agent/ai/dist/config-path.d.ts +2 -0
- package/node_modules/@pencil-agent/ai/dist/config-path.d.ts.map +1 -0
- package/node_modules/@pencil-agent/ai/dist/config-path.js +16 -0
- package/node_modules/@pencil-agent/ai/dist/config-path.js.map +1 -0
- package/node_modules/@pencil-agent/ai/dist/debug-logger.d.ts +95 -0
- package/node_modules/@pencil-agent/ai/dist/debug-logger.d.ts.map +1 -0
- package/node_modules/@pencil-agent/ai/dist/debug-logger.js +218 -0
- package/node_modules/@pencil-agent/ai/dist/debug-logger.js.map +1 -0
- package/node_modules/@pencil-agent/ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/node_modules/@pencil-agent/ai/dist/providers/openai-completions.js +152 -14
- package/node_modules/@pencil-agent/ai/dist/providers/openai-completions.js.map +1 -1
- package/package.json +5 -3
- package/dist/packages/agent-core/src/agent-loop.d.ts +0 -27
- package/dist/packages/agent-core/src/agent-loop.js +0 -314
- package/dist/packages/agent-core/src/agent.d.ts +0 -163
- package/dist/packages/agent-core/src/agent.js +0 -416
- package/dist/packages/agent-core/src/index.d.ts +0 -11
- package/dist/packages/agent-core/src/index.js +0 -15
- package/dist/packages/agent-core/src/proxy.d.ts +0 -91
- package/dist/packages/agent-core/src/proxy.js +0 -274
- package/dist/packages/agent-core/src/types.d.ts +0 -184
- package/dist/packages/agent-core/src/types.js +0 -8
- package/dist/packages/ai/src/api-registry.d.ts +0 -26
- package/dist/packages/ai/src/api-registry.js +0 -50
- package/dist/packages/ai/src/env-api-keys.d.ts +0 -9
- package/dist/packages/ai/src/env-api-keys.js +0 -106
- package/dist/packages/ai/src/index.d.ts +0 -28
- package/dist/packages/ai/src/index.js +0 -21
- package/dist/packages/ai/src/models.d.ts +0 -30
- package/dist/packages/ai/src/models.generated.d.ts +0 -14525
- package/dist/packages/ai/src/models.generated.js +0 -14307
- package/dist/packages/ai/src/models.js +0 -61
- package/dist/packages/ai/src/providers/amazon-bedrock.d.ts +0 -21
- package/dist/packages/ai/src/providers/amazon-bedrock.js +0 -603
- package/dist/packages/ai/src/providers/anthropic.d.ts +0 -39
- package/dist/packages/ai/src/providers/anthropic.js +0 -735
- package/dist/packages/ai/src/providers/azure-openai-responses.d.ts +0 -21
- package/dist/packages/ai/src/providers/azure-openai-responses.js +0 -190
- package/dist/packages/ai/src/providers/github-copilot-headers.d.ts +0 -14
- package/dist/packages/ai/src/providers/github-copilot-headers.js +0 -35
- package/dist/packages/ai/src/providers/google-gemini-cli.d.ts +0 -80
- package/dist/packages/ai/src/providers/google-gemini-cli.js +0 -750
- package/dist/packages/ai/src/providers/google-shared.d.ts +0 -71
- package/dist/packages/ai/src/providers/google-shared.js +0 -312
- package/dist/packages/ai/src/providers/google-vertex.d.ts +0 -21
- package/dist/packages/ai/src/providers/google-vertex.js +0 -377
- package/dist/packages/ai/src/providers/google.d.ts +0 -19
- package/dist/packages/ai/src/providers/google.js +0 -358
- package/dist/packages/ai/src/providers/openai-codex-responses.d.ts +0 -9
- package/dist/packages/ai/src/providers/openai-codex-responses.js +0 -705
- package/dist/packages/ai/src/providers/openai-completions.d.ts +0 -21
- package/dist/packages/ai/src/providers/openai-completions.js +0 -733
- package/dist/packages/ai/src/providers/openai-responses-shared.d.ts +0 -23
- package/dist/packages/ai/src/providers/openai-responses-shared.js +0 -433
- package/dist/packages/ai/src/providers/openai-responses.d.ts +0 -19
- package/dist/packages/ai/src/providers/openai-responses.js +0 -204
- package/dist/packages/ai/src/providers/register-builtins.d.ts +0 -9
- package/dist/packages/ai/src/providers/register-builtins.js +0 -69
- package/dist/packages/ai/src/providers/simple-options.d.ts +0 -14
- package/dist/packages/ai/src/providers/simple-options.js +0 -41
- package/dist/packages/ai/src/providers/transform-messages.d.ts +0 -14
- package/dist/packages/ai/src/providers/transform-messages.js +0 -161
- package/dist/packages/ai/src/stream.d.ts +0 -15
- package/dist/packages/ai/src/stream.js +0 -34
- package/dist/packages/ai/src/types.d.ts +0 -287
- package/dist/packages/ai/src/types.js +0 -8
- package/dist/packages/ai/src/utils/event-stream.d.ts +0 -27
- package/dist/packages/ai/src/utils/event-stream.js +0 -87
- package/dist/packages/ai/src/utils/http-proxy.d.ts +0 -14
- package/dist/packages/ai/src/utils/http-proxy.js +0 -21
- package/dist/packages/ai/src/utils/json-parse.d.ts +0 -15
- package/dist/packages/ai/src/utils/json-parse.js +0 -35
- package/dist/packages/ai/src/utils/oauth/anthropic.d.ts +0 -23
- package/dist/packages/ai/src/utils/oauth/anthropic.js +0 -110
- package/dist/packages/ai/src/utils/oauth/github-copilot.d.ts +0 -36
- package/dist/packages/ai/src/utils/oauth/github-copilot.js +0 -287
- package/dist/packages/ai/src/utils/oauth/google-antigravity.d.ts +0 -32
- package/dist/packages/ai/src/utils/oauth/google-antigravity.js +0 -379
- package/dist/packages/ai/src/utils/oauth/google-gemini-cli.d.ts +0 -32
- package/dist/packages/ai/src/utils/oauth/google-gemini-cli.js +0 -484
- package/dist/packages/ai/src/utils/oauth/index.d.ts +0 -68
- package/dist/packages/ai/src/utils/oauth/index.js +0 -139
- package/dist/packages/ai/src/utils/oauth/openai-codex.d.ts +0 -40
- package/dist/packages/ai/src/utils/oauth/openai-codex.js +0 -386
- package/dist/packages/ai/src/utils/oauth/pkce.d.ts +0 -19
- package/dist/packages/ai/src/utils/oauth/pkce.js +0 -37
- package/dist/packages/ai/src/utils/oauth/types.d.ts +0 -53
- package/dist/packages/ai/src/utils/oauth/types.js +0 -8
- package/dist/packages/ai/src/utils/overflow.d.ts +0 -58
- package/dist/packages/ai/src/utils/overflow.js +0 -121
- package/dist/packages/ai/src/utils/sanitize-unicode.d.ts +0 -28
- package/dist/packages/ai/src/utils/sanitize-unicode.js +0 -32
- package/dist/packages/ai/src/utils/typebox-helpers.d.ts +0 -23
- package/dist/packages/ai/src/utils/typebox-helpers.js +0 -27
- package/dist/packages/ai/src/utils/validation.d.ts +0 -24
- package/dist/packages/ai/src/utils/validation.js +0 -78
- package/dist/packages/tui/src/autocomplete.d.ts +0 -56
- package/dist/packages/tui/src/autocomplete.js +0 -602
- package/dist/packages/tui/src/components/box.d.ts +0 -28
- package/dist/packages/tui/src/components/box.js +0 -110
- package/dist/packages/tui/src/components/cancellable-loader.d.ts +0 -28
- package/dist/packages/tui/src/components/cancellable-loader.js +0 -41
- package/dist/packages/tui/src/components/editor.d.ts +0 -211
- package/dist/packages/tui/src/components/editor.js +0 -1692
- package/dist/packages/tui/src/components/image.d.ts +0 -34
- package/dist/packages/tui/src/components/image.js +0 -75
- package/dist/packages/tui/src/components/input.d.ts +0 -43
- package/dist/packages/tui/src/components/input.js +0 -439
- package/dist/packages/tui/src/components/loader.d.ts +0 -27
- package/dist/packages/tui/src/components/loader.js +0 -55
- package/dist/packages/tui/src/components/markdown.d.ts +0 -101
- package/dist/packages/tui/src/components/markdown.js +0 -635
- package/dist/packages/tui/src/components/select-list.d.ts +0 -38
- package/dist/packages/tui/src/components/select-list.js +0 -158
- package/dist/packages/tui/src/components/settings-list.d.ts +0 -56
- package/dist/packages/tui/src/components/settings-list.js +0 -191
- package/dist/packages/tui/src/components/spacer.d.ts +0 -18
- package/dist/packages/tui/src/components/spacer.js +0 -29
- package/dist/packages/tui/src/components/text.d.ts +0 -25
- package/dist/packages/tui/src/components/text.js +0 -95
- package/dist/packages/tui/src/components/truncated-text.d.ts +0 -19
- package/dist/packages/tui/src/components/truncated-text.js +0 -57
- package/dist/packages/tui/src/editor-component.d.ts +0 -45
- package/dist/packages/tui/src/editor-component.js +0 -8
- package/dist/packages/tui/src/fuzzy.d.ts +0 -22
- package/dist/packages/tui/src/fuzzy.js +0 -113
- package/dist/packages/tui/src/index.d.ts +0 -29
- package/dist/packages/tui/src/index.js +0 -38
- package/dist/packages/tui/src/keybindings.d.ts +0 -45
- package/dist/packages/tui/src/keybindings.js +0 -120
- package/dist/packages/tui/src/keys.d.ts +0 -166
- package/dist/packages/tui/src/keys.js +0 -965
- package/dist/packages/tui/src/kill-ring.d.ts +0 -34
- package/dist/packages/tui/src/kill-ring.js +0 -50
- package/dist/packages/tui/src/stdin-buffer.d.ts +0 -54
- package/dist/packages/tui/src/stdin-buffer.js +0 -323
- package/dist/packages/tui/src/terminal-image.d.ts +0 -74
- package/dist/packages/tui/src/terminal-image.js +0 -288
- package/dist/packages/tui/src/terminal.d.ts +0 -84
- package/dist/packages/tui/src/terminal.js +0 -255
- package/dist/packages/tui/src/tui.d.ts +0 -216
- package/dist/packages/tui/src/tui.js +0 -961
- package/dist/packages/tui/src/undo-stack.d.ts +0 -23
- package/dist/packages/tui/src/undo-stack.js +0 -31
- package/dist/packages/tui/src/utils.d.ts +0 -84
- package/dist/packages/tui/src/utils.js +0 -812
- package/node_modules/ast-types/.DS_Store +0 -0
- package/node_modules/fast-uri/.DS_Store +0 -0
- package/node_modules/json-schema-traverse/.DS_Store +0 -0
- package/node_modules/koffi/.DS_Store +0 -0
- package/node_modules/netmask/.DS_Store +0 -0
- package/node_modules/openai/.DS_Store +0 -0
- package/node_modules/smart-buffer/.DS_Store +0 -0
- package/node_modules/socks/.DS_Store +0 -0
- package/node_modules/strnum/.DS_Store +0 -0
- package/node_modules/undici/.DS_Store +0 -0
- package/node_modules/zod-to-json-schema/.DS_Store +0 -0
package/dist/cli.js
CHANGED
|
File without changes
|
|
@@ -97,6 +97,10 @@ export interface Settings {
|
|
|
97
97
|
lockStaleMinutes?: number;
|
|
98
98
|
};
|
|
99
99
|
};
|
|
100
|
+
/** Auto-update setting: 'always' = auto-update on startup, 'prompt' = ask user (default), 'never' = never check */
|
|
101
|
+
autoUpdate?: "always" | "prompt" | "never";
|
|
102
|
+
/** Last skipped version for update prompts */
|
|
103
|
+
skippedVersion?: string;
|
|
100
104
|
}
|
|
101
105
|
export type SettingsScope = "global" | "project";
|
|
102
106
|
export interface SettingsStorage {
|
|
@@ -251,5 +255,9 @@ export declare class SettingsManager {
|
|
|
251
255
|
getAutocompleteMaxVisible(): number;
|
|
252
256
|
setAutocompleteMaxVisible(maxVisible: number): void;
|
|
253
257
|
getCodeBlockIndent(): string;
|
|
258
|
+
getAutoUpdate(): "always" | "prompt" | "never";
|
|
259
|
+
setAutoUpdate(mode: "always" | "prompt" | "never"): void;
|
|
260
|
+
getSkippedVersion(): string | undefined;
|
|
261
|
+
setSkippedVersion(version: string | undefined): void;
|
|
254
262
|
}
|
|
255
263
|
//# sourceMappingURL=settings-manager.d.ts.map
|
|
@@ -689,5 +689,21 @@ export class SettingsManager {
|
|
|
689
689
|
getCodeBlockIndent() {
|
|
690
690
|
return this.settings.markdown?.codeBlockIndent ?? " ";
|
|
691
691
|
}
|
|
692
|
+
getAutoUpdate() {
|
|
693
|
+
return this.settings.autoUpdate ?? "prompt";
|
|
694
|
+
}
|
|
695
|
+
setAutoUpdate(mode) {
|
|
696
|
+
this.globalSettings.autoUpdate = mode;
|
|
697
|
+
this.markModified("autoUpdate");
|
|
698
|
+
this.save();
|
|
699
|
+
}
|
|
700
|
+
getSkippedVersion() {
|
|
701
|
+
return this.settings.skippedVersion;
|
|
702
|
+
}
|
|
703
|
+
setSkippedVersion(version) {
|
|
704
|
+
this.globalSettings.skippedVersion = version;
|
|
705
|
+
this.markModified("skippedVersion");
|
|
706
|
+
this.save();
|
|
707
|
+
}
|
|
692
708
|
}
|
|
693
709
|
//# sourceMappingURL=settings-manager.js.map
|
package/dist/core/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type { CompactionResult } from "./session/compaction/index.js";
|
|
|
10
10
|
export { createEventBus, type EventBus, type EventBusController, } from "./runtime/event-bus.js";
|
|
11
11
|
export { type AgentEndEvent, type AgentStartEvent, type AgentToolResult, type AgentToolUpdateCallback, type BeforeAgentStartEvent, type ContextEvent, discoverAndLoadExtensions, type ExecOptions, type ExecResult, type Extension, type ExtensionAPI, type ExtensionCommandContext, type ExtensionContext, type ExtensionError, type ExtensionEvent, type ExtensionFactory, type ExtensionFlag, type ExtensionHandler, ExtensionRunner, type ExtensionShortcut, type ExtensionUIContext, type LoadExtensionsResult, type MessageRenderer, type RegisteredCommand, type SessionBeforeCompactEvent, type SessionBeforeForkEvent, type SessionBeforeSwitchEvent, type SessionBeforeTreeEvent, type SessionCompactEvent, type SessionForkEvent, type SessionShutdownEvent, type SessionStartEvent, type SessionSwitchEvent, type SessionTreeEvent, type ToolCallEvent, type ToolDefinition, type ToolRenderResultOptions, type ToolResultEvent, type TurnEndEvent, type TurnStartEvent, wrapToolsWithExtensions, } from "./extensions/index.js";
|
|
12
12
|
export { MCPManager } from "./mcp-manager.js";
|
|
13
|
+
export { getDebugLogger, createDebugLogger, debug, type DebugLogLevel, } from "../packages/ai/dist/debug-logger.js";
|
|
13
14
|
export type { MCPServerConfig, MCPTool, MCPToolResult, } from "./mcp/mcp-client.js";
|
|
14
15
|
export { loadMCPConfig, saveMCPConfig, addMCPServer, removeMCPServer, getMCPServer, listMCPServers, listEnabledMCPServers, } from "./mcp/mcp-config.js";
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/index.js
CHANGED
|
@@ -11,5 +11,7 @@ export { createEventBus, } from "./runtime/event-bus.js";
|
|
|
11
11
|
export { discoverAndLoadExtensions, ExtensionRunner, wrapToolsWithExtensions, } from "./extensions/index.js";
|
|
12
12
|
// MCP (Model Context Protocol) support
|
|
13
13
|
export { MCPManager } from "./mcp-manager.js";
|
|
14
|
+
// Debug logging (re-exported from ai package)
|
|
15
|
+
export { getDebugLogger, createDebugLogger, debug, } from "../packages/ai/dist/debug-logger.js";
|
|
14
16
|
export { loadMCPConfig, saveMCPConfig, addMCPServer, removeMCPServer, getMCPServer, listMCPServers, listEnabledMCPServers, } from "./mcp/mcp-config.js";
|
|
15
17
|
//# sourceMappingURL=index.js.map
|
|
@@ -40,7 +40,7 @@ export declare class ModelSwitcher {
|
|
|
40
40
|
*/
|
|
41
41
|
hasApiKey(model: Model<any>): Promise<boolean>;
|
|
42
42
|
/**
|
|
43
|
-
* Get models with API keys
|
|
43
|
+
* Get models with API keys (async, validates OAuth tokens)
|
|
44
44
|
*/
|
|
45
45
|
getModelsWithApiKey(): Promise<Model<any>[]>;
|
|
46
46
|
/**
|
|
@@ -60,6 +60,7 @@ export declare class ModelSwitcher {
|
|
|
60
60
|
private cycleScopedModel;
|
|
61
61
|
/**
|
|
62
62
|
* Cycle through all available models
|
|
63
|
+
* Skips models with expired OAuth tokens.
|
|
63
64
|
*/
|
|
64
65
|
private cycleAvailableModel;
|
|
65
66
|
/**
|
|
@@ -20,13 +20,14 @@ export class ModelSwitcher {
|
|
|
20
20
|
return !!apiKey;
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
|
-
* Get models with API keys
|
|
23
|
+
* Get models with API keys (async, validates OAuth tokens)
|
|
24
24
|
*/
|
|
25
25
|
async getModelsWithApiKey() {
|
|
26
26
|
const available = this.options.getAvailableModels();
|
|
27
27
|
const result = [];
|
|
28
28
|
for (const model of available) {
|
|
29
|
-
|
|
29
|
+
const apiKey = await this.options.getApiKey(model);
|
|
30
|
+
if (apiKey) {
|
|
30
31
|
result.push(model);
|
|
31
32
|
}
|
|
32
33
|
}
|
|
@@ -89,9 +90,10 @@ export class ModelSwitcher {
|
|
|
89
90
|
}
|
|
90
91
|
/**
|
|
91
92
|
* Cycle through all available models
|
|
93
|
+
* Skips models with expired OAuth tokens.
|
|
92
94
|
*/
|
|
93
95
|
async cycleAvailableModel(direction) {
|
|
94
|
-
const available =
|
|
96
|
+
const available = this.options.getAvailableModels();
|
|
95
97
|
if (available.length <= 1)
|
|
96
98
|
return undefined;
|
|
97
99
|
const currentModel = this.getModel();
|
|
@@ -99,11 +101,32 @@ export class ModelSwitcher {
|
|
|
99
101
|
if (currentIndex === -1)
|
|
100
102
|
currentIndex = 0;
|
|
101
103
|
const len = available.length;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
// Find next model with valid API key, skipping expired OAuth tokens
|
|
105
|
+
let nextIndex = currentIndex;
|
|
106
|
+
let attempts = 0;
|
|
107
|
+
let next;
|
|
106
108
|
const previousModel = currentModel;
|
|
109
|
+
while (attempts < len - 1) {
|
|
110
|
+
attempts++;
|
|
111
|
+
nextIndex =
|
|
112
|
+
direction === "forward"
|
|
113
|
+
? (nextIndex + 1) % len
|
|
114
|
+
: (nextIndex - 1 + len) % len;
|
|
115
|
+
const candidate = available[nextIndex];
|
|
116
|
+
if (!candidate)
|
|
117
|
+
continue;
|
|
118
|
+
// Use async getApiKey to validate OAuth tokens
|
|
119
|
+
const apiKey = await this.options.getApiKey(candidate);
|
|
120
|
+
if (apiKey) {
|
|
121
|
+
next = candidate;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
// No valid key - skip this model and continue cycling
|
|
125
|
+
}
|
|
126
|
+
if (!next) {
|
|
127
|
+
// No models have valid API keys
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
107
130
|
// Set the new model
|
|
108
131
|
this.options.setModelOnAgent(next);
|
|
109
132
|
return {
|
|
@@ -58,6 +58,11 @@ export declare class ModelRegistry {
|
|
|
58
58
|
* This is a fast check that doesn't refresh OAuth tokens.
|
|
59
59
|
*/
|
|
60
60
|
getAvailable(): Model<Api>[];
|
|
61
|
+
/**
|
|
62
|
+
* Get models with valid API keys (async, validates OAuth tokens).
|
|
63
|
+
* This checks and refreshes OAuth tokens, filtering out expired ones.
|
|
64
|
+
*/
|
|
65
|
+
getAvailableAsync(): Promise<Model<Api>[]>;
|
|
61
66
|
/**
|
|
62
67
|
* Find a model by provider and ID.
|
|
63
68
|
*/
|
|
@@ -83,6 +88,15 @@ export declare class ModelRegistry {
|
|
|
83
88
|
*/
|
|
84
89
|
registerProvider(providerName: string, config: ProviderConfigInput): void;
|
|
85
90
|
private applyProviderConfig;
|
|
91
|
+
private static readonly OPENROUTER_JSON_BASE;
|
|
92
|
+
private static readonly OPENROUTER_JSON_API;
|
|
93
|
+
/**
|
|
94
|
+
* Append an OpenRouter model to models.json by id (same string as on openrouter.ai, e.g. x-ai/grok-4.20).
|
|
95
|
+
* API key is not written; use /login openrouter or OPENROUTER_API_KEY.
|
|
96
|
+
*/
|
|
97
|
+
appendOpenRouterModel(modelId: string, options?: {
|
|
98
|
+
name?: string;
|
|
99
|
+
}): void;
|
|
86
100
|
}
|
|
87
101
|
/**
|
|
88
102
|
* Input type for registerProvider API.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { getModels, getProviders, registerApiProvider, registerOAuthProvider, } from "@pencil-agent/ai";
|
|
8
8
|
import { Type } from "@sinclair/typebox";
|
|
9
9
|
import AjvModule from "ajv";
|
|
10
|
-
import { existsSync, readFileSync } from "fs";
|
|
10
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
11
11
|
import { join } from "path";
|
|
12
12
|
import { getAgentDir } from "../config.js";
|
|
13
13
|
import { clearConfigValueCache, resolveConfigValue, resolveHeaders } from "./config/resolve-config-value.js";
|
|
@@ -411,6 +411,20 @@ export class ModelRegistry {
|
|
|
411
411
|
getAvailable() {
|
|
412
412
|
return this.models.filter((m) => this.authStorage.hasAuth(m.provider));
|
|
413
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Get models with valid API keys (async, validates OAuth tokens).
|
|
416
|
+
* This checks and refreshes OAuth tokens, filtering out expired ones.
|
|
417
|
+
*/
|
|
418
|
+
async getAvailableAsync() {
|
|
419
|
+
const result = [];
|
|
420
|
+
for (const model of this.models) {
|
|
421
|
+
const apiKey = await this.authStorage.getApiKey(model.provider);
|
|
422
|
+
if (apiKey) {
|
|
423
|
+
result.push(model);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return result;
|
|
427
|
+
}
|
|
414
428
|
/**
|
|
415
429
|
* Find a model by provider and ID.
|
|
416
430
|
*/
|
|
@@ -536,5 +550,54 @@ export class ModelRegistry {
|
|
|
536
550
|
});
|
|
537
551
|
}
|
|
538
552
|
}
|
|
553
|
+
static OPENROUTER_JSON_BASE = "https://openrouter.ai/api/v1";
|
|
554
|
+
static OPENROUTER_JSON_API = "openai-completions";
|
|
555
|
+
/**
|
|
556
|
+
* Append an OpenRouter model to models.json by id (same string as on openrouter.ai, e.g. x-ai/grok-4.20).
|
|
557
|
+
* API key is not written; use /login openrouter or OPENROUTER_API_KEY.
|
|
558
|
+
*/
|
|
559
|
+
appendOpenRouterModel(modelId, options) {
|
|
560
|
+
const providerKey = "openrouter";
|
|
561
|
+
const trimmed = modelId.trim();
|
|
562
|
+
if (!trimmed) {
|
|
563
|
+
throw new Error("OpenRouter model id cannot be empty");
|
|
564
|
+
}
|
|
565
|
+
const modelsPath = this.modelsJsonPath;
|
|
566
|
+
if (!modelsPath) {
|
|
567
|
+
throw new Error("models.json path is not configured");
|
|
568
|
+
}
|
|
569
|
+
let data;
|
|
570
|
+
if (existsSync(modelsPath)) {
|
|
571
|
+
const raw = readFileSync(modelsPath, "utf-8");
|
|
572
|
+
data = JSON.parse(raw);
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
data = { providers: {} };
|
|
576
|
+
}
|
|
577
|
+
if (!data.providers || typeof data.providers !== "object") {
|
|
578
|
+
data.providers = {};
|
|
579
|
+
}
|
|
580
|
+
const existing = data.providers[providerKey] ?? {};
|
|
581
|
+
const prevModels = Array.isArray(existing.models) ? [...existing.models] : [];
|
|
582
|
+
if (prevModels.some((m) => m && typeof m === "object" && m.id === trimmed)) {
|
|
583
|
+
throw new Error(`OpenRouter model "${trimmed}" already exists in models.json`);
|
|
584
|
+
}
|
|
585
|
+
const displayName = options?.name?.trim() || trimmed;
|
|
586
|
+
prevModels.push({
|
|
587
|
+
id: trimmed,
|
|
588
|
+
name: displayName,
|
|
589
|
+
input: ["text"],
|
|
590
|
+
contextWindow: 256000,
|
|
591
|
+
maxTokens: 8192,
|
|
592
|
+
});
|
|
593
|
+
data.providers[providerKey] = {
|
|
594
|
+
...existing,
|
|
595
|
+
baseUrl: existing.baseUrl ?? ModelRegistry.OPENROUTER_JSON_BASE,
|
|
596
|
+
api: existing.api ?? ModelRegistry.OPENROUTER_JSON_API,
|
|
597
|
+
models: prevModels,
|
|
598
|
+
};
|
|
599
|
+
writeFileSync(modelsPath, JSON.stringify(data, null, 2), "utf-8");
|
|
600
|
+
this.refresh();
|
|
601
|
+
}
|
|
539
602
|
}
|
|
540
603
|
//# sourceMappingURL=model-registry.js.map
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { Agent, AgentEvent, AgentMessage, AgentState, AgentTool, ThinkingLevel } from "@pencil-agent/agent-core";
|
|
2
2
|
import type { ImageContent, Model, TextContent } from "@pencil-agent/ai";
|
|
3
|
+
/**
|
|
4
|
+
* Custom error for model cycling with additional context.
|
|
5
|
+
*/
|
|
6
|
+
export declare class CycleModelError extends Error {
|
|
7
|
+
readonly provider?: string | undefined;
|
|
8
|
+
readonly code?: "oauth_expired" | "no_valid_key" | "api_error" | undefined;
|
|
9
|
+
constructor(message: string, provider?: string | undefined, code?: "oauth_expired" | "no_valid_key" | "api_error" | undefined);
|
|
10
|
+
}
|
|
3
11
|
import { type BashResult } from "../bash-executor.js";
|
|
4
12
|
import { type CompactionResult } from "../session/compaction/index.js";
|
|
5
13
|
import { CompactionCoordinator } from "../session/compaction/compaction-coordinator.js";
|
|
@@ -19,6 +19,19 @@ import { getDocsPath } from "../../config.js";
|
|
|
19
19
|
import { theme } from "../../modes/interactive/theme/theme.js";
|
|
20
20
|
import { stripFrontmatter } from "../../utils/frontmatter.js";
|
|
21
21
|
import { sleep } from "../utils/sleep.js";
|
|
22
|
+
/**
|
|
23
|
+
* Custom error for model cycling with additional context.
|
|
24
|
+
*/
|
|
25
|
+
export class CycleModelError extends Error {
|
|
26
|
+
provider;
|
|
27
|
+
code;
|
|
28
|
+
constructor(message, provider, code) {
|
|
29
|
+
super(message);
|
|
30
|
+
this.provider = provider;
|
|
31
|
+
this.code = code;
|
|
32
|
+
this.name = "CycleModelError";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
22
35
|
import { executeBash as executeBashCommand, executeBashWithOperations, } from "../bash-executor.js";
|
|
23
36
|
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "../session/compaction/index.js";
|
|
24
37
|
import { CompactionCoordinator } from "../session/compaction/compaction-coordinator.js";
|
|
@@ -1190,7 +1203,8 @@ export class AgentSession {
|
|
|
1190
1203
|
};
|
|
1191
1204
|
}
|
|
1192
1205
|
async _cycleAvailableModel(direction) {
|
|
1193
|
-
|
|
1206
|
+
// Use getAvailableAsync to pre-filter models with invalid OAuth tokens
|
|
1207
|
+
const availableModels = await this._modelRegistry.getAvailableAsync();
|
|
1194
1208
|
if (availableModels.length <= 1)
|
|
1195
1209
|
return undefined;
|
|
1196
1210
|
const currentModel = this.model;
|
|
@@ -1198,13 +1212,38 @@ export class AgentSession {
|
|
|
1198
1212
|
if (currentIndex === -1)
|
|
1199
1213
|
currentIndex = 0;
|
|
1200
1214
|
const len = availableModels.length;
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1215
|
+
// Find next model with valid API key, skipping expired OAuth tokens
|
|
1216
|
+
// Start from nextIndex and loop through all models
|
|
1217
|
+
const startIndex = currentIndex;
|
|
1218
|
+
let nextIndex = currentIndex;
|
|
1219
|
+
let attempts = 0;
|
|
1220
|
+
let nextModel;
|
|
1221
|
+
let apiKey;
|
|
1222
|
+
while (attempts < len - 1) {
|
|
1223
|
+
attempts++;
|
|
1224
|
+
nextIndex =
|
|
1225
|
+
direction === "forward"
|
|
1226
|
+
? (nextIndex + 1) % len
|
|
1227
|
+
: (nextIndex - 1 + len) % len;
|
|
1228
|
+
const candidate = availableModels[nextIndex];
|
|
1229
|
+
if (!candidate)
|
|
1230
|
+
continue;
|
|
1231
|
+
// Use async getApiKey to validate OAuth tokens
|
|
1232
|
+
apiKey = await this._modelRegistry.getApiKey(candidate);
|
|
1233
|
+
if (apiKey) {
|
|
1234
|
+
nextModel = candidate;
|
|
1235
|
+
break;
|
|
1236
|
+
}
|
|
1237
|
+
// No valid key - skip this model and continue cycling
|
|
1238
|
+
}
|
|
1239
|
+
if (!nextModel || !apiKey) {
|
|
1240
|
+
// No models have valid API keys (all OAuth tokens expired or no keys)
|
|
1241
|
+
const provider = currentModel?.provider;
|
|
1242
|
+
const cred = provider ? this._modelRegistry.authStorage.get(provider) : undefined;
|
|
1243
|
+
if (cred?.type === "oauth") {
|
|
1244
|
+
throw new CycleModelError(`All available models have expired OAuth tokens. Use /login ${provider} to re-authenticate.`, provider, "oauth_expired");
|
|
1245
|
+
}
|
|
1246
|
+
throw new CycleModelError(`No models with valid API keys available`, provider, "no_valid_key");
|
|
1208
1247
|
}
|
|
1209
1248
|
this.agent.setModel(nextModel);
|
|
1210
1249
|
this.sessionManager.appendModelChange(nextModel.provider, nextModel.id);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* [UPSTREAM]:
|
|
3
|
-
* [SURFACE]:
|
|
2
|
+
* [UPSTREAM]:
|
|
3
|
+
* [SURFACE]:
|
|
4
4
|
* [LOCUS]: modes/interactive/components/custom-editor.ts -
|
|
5
5
|
* [COVENANT]: Change → update this header
|
|
6
6
|
*/
|
|
@@ -17,6 +17,8 @@ export declare class CustomEditor extends Editor {
|
|
|
17
17
|
onPasteImage?: () => void;
|
|
18
18
|
/** Handler for extension-registered shortcuts. Returns true if handled. */
|
|
19
19
|
onExtensionShortcut?: (data: string) => boolean;
|
|
20
|
+
/** Handler for attachment navigation (arrow keys, delete). Returns true if handled. */
|
|
21
|
+
onAttachmentKey?: (data: string) => boolean;
|
|
20
22
|
constructor(tui: TUI, theme: EditorTheme, keybindings: KeybindingsManager, options?: EditorOptions);
|
|
21
23
|
/**
|
|
22
24
|
* Register a handler for an app action.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* [UPSTREAM]:
|
|
3
|
-
* [SURFACE]:
|
|
2
|
+
* [UPSTREAM]:
|
|
3
|
+
* [SURFACE]:
|
|
4
4
|
* [LOCUS]: modes/interactive/components/custom-editor.ts -
|
|
5
5
|
* [COVENANT]: Change → update this header
|
|
6
6
|
*/
|
|
7
|
-
import { Editor } from "@pencil-agent/tui";
|
|
7
|
+
import { Editor, getEditorKeybindings, matchesKey } from "@pencil-agent/tui";
|
|
8
8
|
/**
|
|
9
9
|
* Custom editor that handles app-level keybindings for coding-agent.
|
|
10
10
|
*/
|
|
@@ -17,6 +17,8 @@ export class CustomEditor extends Editor {
|
|
|
17
17
|
onPasteImage;
|
|
18
18
|
/** Handler for extension-registered shortcuts. Returns true if handled. */
|
|
19
19
|
onExtensionShortcut;
|
|
20
|
+
/** Handler for attachment navigation (arrow keys, delete). Returns true if handled. */
|
|
21
|
+
onAttachmentKey;
|
|
20
22
|
constructor(tui, theme, keybindings, options) {
|
|
21
23
|
super(tui, theme, options);
|
|
22
24
|
this.keybindings = keybindings;
|
|
@@ -32,10 +34,19 @@ export class CustomEditor extends Editor {
|
|
|
32
34
|
if (this.onExtensionShortcut?.(data)) {
|
|
33
35
|
return;
|
|
34
36
|
}
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
// Detect image paste via empty bracketed paste — the terminal sends an
|
|
38
|
+
// empty bracket sequence when the clipboard contains an image (since
|
|
39
|
+
// raw image bytes can't be pasted as text). This is the ONLY trigger
|
|
40
|
+
// for clipboard image reading; we intentionally do NOT intercept the
|
|
41
|
+
// raw Ctrl+V key code because Windows keeps stale image data in the
|
|
42
|
+
// clipboard even after the user copies text, which would cause the
|
|
43
|
+
// wrong content to be pasted.
|
|
44
|
+
if (this.onPasteImage && data.includes("\x1b[200~") && data.includes("\x1b[201~")) {
|
|
45
|
+
const content = data.replace("\x1b[200~", "").replace("\x1b[201~", "").trim();
|
|
46
|
+
if (content.length === 0) {
|
|
47
|
+
this.onPasteImage();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
39
50
|
}
|
|
40
51
|
// Check app keybindings first
|
|
41
52
|
// Escape/interrupt - only if autocomplete is NOT active
|
|
@@ -69,6 +80,21 @@ export class CustomEditor extends Editor {
|
|
|
69
80
|
return;
|
|
70
81
|
}
|
|
71
82
|
}
|
|
83
|
+
// Forward navigation/delete keys to the attachment handler. The handler
|
|
84
|
+
// only consumes them when appropriate (e.g. Delete only when an
|
|
85
|
+
// attachment is selected), otherwise returns false so the editor
|
|
86
|
+
// processes the key normally.
|
|
87
|
+
if (this.onAttachmentKey) {
|
|
88
|
+
const kb = getEditorKeybindings();
|
|
89
|
+
if (kb.matches(data, "cursorUp") ||
|
|
90
|
+
kb.matches(data, "cursorDown") ||
|
|
91
|
+
matchesKey(data, "delete") ||
|
|
92
|
+
matchesKey(data, "backspace")) {
|
|
93
|
+
if (this.onAttachmentKey(data)) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
72
98
|
// Pass to parent for editor handling
|
|
73
99
|
super.handleInput(data);
|
|
74
100
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* [COVENANT]: Change components → update this header
|
|
6
6
|
*/
|
|
7
7
|
export { ArminComponent } from "./armin.js";
|
|
8
|
+
export { AttachmentsBarComponent } from "./attachments-bar.js";
|
|
8
9
|
export { AssistantMessageComponent } from "./assistant-message.js";
|
|
9
10
|
export { promptForApiKey } from "./apikey-input.js";
|
|
10
11
|
export { BashExecutionComponent } from "./bash-execution.js";
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
// UI Components for extensions
|
|
8
8
|
export { ArminComponent } from "./armin.js";
|
|
9
|
+
export { AttachmentsBarComponent } from "./attachments-bar.js";
|
|
9
10
|
export { AssistantMessageComponent } from "./assistant-message.js";
|
|
10
11
|
export { promptForApiKey } from "./apikey-input.js";
|
|
11
12
|
export { BashExecutionComponent } from "./bash-execution.js";
|
|
@@ -35,9 +35,11 @@ export declare class ModelSelectorComponent extends Container implements Focusab
|
|
|
35
35
|
private scopeText?;
|
|
36
36
|
private scopeHintText?;
|
|
37
37
|
private filterByProvider?;
|
|
38
|
+
/** When set, Ctrl+N runs this (parent closes selector and prompts for OpenRouter model id). */
|
|
39
|
+
private onAddOpenRouterModel?;
|
|
38
40
|
get focused(): boolean;
|
|
39
41
|
set focused(value: boolean);
|
|
40
|
-
constructor(tui: TUI, currentModel: Model<any> | undefined, settingsManager: SettingsManager, modelRegistry: ModelRegistry, scopedModels: ReadonlyArray<ScopedModelItem>, ensureProviderConfigured: EnsureProviderConfigured | undefined, onSelect: (model: Model<any>) => void, onCancel: () => void, initialSearchInput?: string, filterByProvider?: string);
|
|
42
|
+
constructor(tui: TUI, currentModel: Model<any> | undefined, settingsManager: SettingsManager, modelRegistry: ModelRegistry, scopedModels: ReadonlyArray<ScopedModelItem>, ensureProviderConfigured: EnsureProviderConfigured | undefined, onSelect: (model: Model<any>) => void, onCancel: () => void, initialSearchInput?: string, filterByProvider?: string, onAddOpenRouterModel?: () => void);
|
|
41
43
|
private loadModels;
|
|
42
44
|
private sortModels;
|
|
43
45
|
private getScopeText;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* [COVENANT]: Change → update this header
|
|
6
6
|
*/
|
|
7
7
|
import { modelsAreEqual } from "@pencil-agent/ai";
|
|
8
|
-
import { Container, fuzzyFilter, getEditorKeybindings, Input, Spacer, Text, } from "@pencil-agent/tui";
|
|
8
|
+
import { Container, fuzzyFilter, getEditorKeybindings, Input, matchesKey, Spacer, Text, } from "@pencil-agent/tui";
|
|
9
9
|
import { theme } from "../theme/theme.js";
|
|
10
10
|
import { promptForApiKey } from "./apikey-input.js";
|
|
11
11
|
import { DynamicBorder } from "./dynamic-border.js";
|
|
@@ -32,6 +32,8 @@ export class ModelSelectorComponent extends Container {
|
|
|
32
32
|
scopeText;
|
|
33
33
|
scopeHintText;
|
|
34
34
|
filterByProvider;
|
|
35
|
+
/** When set, Ctrl+N runs this (parent closes selector and prompts for OpenRouter model id). */
|
|
36
|
+
onAddOpenRouterModel;
|
|
35
37
|
get focused() {
|
|
36
38
|
return this._focused;
|
|
37
39
|
}
|
|
@@ -39,7 +41,7 @@ export class ModelSelectorComponent extends Container {
|
|
|
39
41
|
this._focused = value;
|
|
40
42
|
this.searchInput.focused = value;
|
|
41
43
|
}
|
|
42
|
-
constructor(tui, currentModel, settingsManager, modelRegistry, scopedModels, ensureProviderConfigured, onSelect, onCancel, initialSearchInput, filterByProvider) {
|
|
44
|
+
constructor(tui, currentModel, settingsManager, modelRegistry, scopedModels, ensureProviderConfigured, onSelect, onCancel, initialSearchInput, filterByProvider, onAddOpenRouterModel) {
|
|
43
45
|
super();
|
|
44
46
|
this.tui = tui;
|
|
45
47
|
this.currentModel = currentModel;
|
|
@@ -48,6 +50,7 @@ export class ModelSelectorComponent extends Container {
|
|
|
48
50
|
this.scopedModels = scopedModels;
|
|
49
51
|
this.ensureProviderConfigured = ensureProviderConfigured;
|
|
50
52
|
this.filterByProvider = filterByProvider;
|
|
53
|
+
this.onAddOpenRouterModel = onAddOpenRouterModel;
|
|
51
54
|
this.scope = scopedModels.length > 0 && !filterByProvider ? "scoped" : "all";
|
|
52
55
|
this.onSelectCallback = onSelect;
|
|
53
56
|
this.onCancelCallback = onCancel;
|
|
@@ -73,6 +76,10 @@ export class ModelSelectorComponent extends Container {
|
|
|
73
76
|
}
|
|
74
77
|
};
|
|
75
78
|
this.addChild(this.searchInput);
|
|
79
|
+
if (this.onAddOpenRouterModel) {
|
|
80
|
+
this.addChild(new Spacer(1));
|
|
81
|
+
this.addChild(new Text(theme.fg("muted", "Ctrl+N: add OpenRouter model by id (same as openrouter.ai)"), 0, 0));
|
|
82
|
+
}
|
|
76
83
|
this.addChild(new Spacer(1));
|
|
77
84
|
this.listContainer = new Container();
|
|
78
85
|
this.addChild(this.listContainer);
|
|
@@ -255,38 +262,63 @@ export class ModelSelectorComponent extends Container {
|
|
|
255
262
|
else if (kb.matches(keyData, "selectCancel")) {
|
|
256
263
|
this.onCancelCallback();
|
|
257
264
|
}
|
|
265
|
+
else if (this.onAddOpenRouterModel && matchesKey(keyData, "ctrl+n")) {
|
|
266
|
+
this.onAddOpenRouterModel();
|
|
267
|
+
}
|
|
258
268
|
else {
|
|
259
269
|
this.searchInput.handleInput(keyData);
|
|
260
270
|
this.filterModels(this.searchInput.getValue());
|
|
261
271
|
}
|
|
262
272
|
}
|
|
263
273
|
async handleSelect(model) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
274
|
+
try {
|
|
275
|
+
if (this.ensureProviderConfigured) {
|
|
276
|
+
const ready = await this.ensureProviderConfigured(model);
|
|
277
|
+
if (!ready) {
|
|
278
|
+
this.onCancelCallback();
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
this.modelRegistry.refresh();
|
|
282
|
+
}
|
|
283
|
+
// Use async getApiKey to validate OAuth tokens (hasAuth is sync and doesn't refresh)
|
|
284
|
+
const apiKey = await this.modelRegistry.authStorage.getApiKey(model.provider);
|
|
285
|
+
if (!apiKey) {
|
|
286
|
+
// Check if this is an OAuth provider with expired/invalid token
|
|
287
|
+
const cred = this.modelRegistry.authStorage.get(model.provider);
|
|
288
|
+
if (cred?.type === "oauth") {
|
|
289
|
+
// OAuth token expired or refresh failed - prompt user to re-login
|
|
290
|
+
// Note: onSelectCallback will handle showing error and suggesting /login
|
|
291
|
+
this.onSelectCallback(model);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
// Non-OAuth provider without key - prompt for API key input
|
|
295
|
+
const providerHints = {
|
|
296
|
+
"dashscope-coding": "DashScope API key (sk-sp-...)",
|
|
297
|
+
"qianfan-coding": "Qianfan API key",
|
|
298
|
+
"ark-coding": "Ark API key",
|
|
299
|
+
openrouter: "OpenRouter API key",
|
|
300
|
+
};
|
|
301
|
+
const prompt = providerHints[model.provider] ?? `${model.provider} API key`;
|
|
302
|
+
const key = await promptForApiKey({ prompt: `Enter ${prompt}` });
|
|
303
|
+
if (!key) {
|
|
304
|
+
this.onCancelCallback();
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
this.modelRegistry.authStorage.set(model.provider, {
|
|
308
|
+
type: "api_key",
|
|
309
|
+
key,
|
|
310
|
+
});
|
|
311
|
+
this.modelRegistry.refresh();
|
|
312
|
+
}
|
|
313
|
+
const refreshedModel = this.modelRegistry.find(model.provider, model.id) ?? model;
|
|
314
|
+
this.settingsManager.setDefaultModelAndProvider(refreshedModel.provider, refreshedModel.id);
|
|
315
|
+
this.onSelectCallback(refreshedModel);
|
|
269
316
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
"ark-coding": "Ark API key",
|
|
275
|
-
openrouter: "OpenRouter API key",
|
|
276
|
-
};
|
|
277
|
-
const prompt = providerHints[model.provider] ?? `${model.provider} API key`;
|
|
278
|
-
const key = await promptForApiKey({ prompt: `Enter ${prompt}` });
|
|
279
|
-
if (!key)
|
|
280
|
-
return;
|
|
281
|
-
this.modelRegistry.authStorage.set(model.provider, {
|
|
282
|
-
type: "api_key",
|
|
283
|
-
key,
|
|
284
|
-
});
|
|
285
|
-
this.modelRegistry.refresh();
|
|
317
|
+
catch (error) {
|
|
318
|
+
// Ensure selector is closed on any error
|
|
319
|
+
this.onCancelCallback();
|
|
320
|
+
throw error;
|
|
286
321
|
}
|
|
287
|
-
const refreshedModel = this.modelRegistry.find(model.provider, model.id) ?? model;
|
|
288
|
-
this.settingsManager.setDefaultModelAndProvider(refreshedModel.provider, refreshedModel.id);
|
|
289
|
-
this.onSelectCallback(refreshedModel);
|
|
290
322
|
}
|
|
291
323
|
getSearchInput() {
|
|
292
324
|
return this.searchInput;
|