mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-18 15:01:36 +00:00
2c19c8d4d2f36e3835bda7225284319dceeb148b
2 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b22c36f112 |
fix: land ten small reliability fixes (#100399)
* fix(cron): reject sub-millisecond durations * fix(skill-workshop): preserve proposal terminal newline Preserve proposal_content exactly at the agent tool boundary and make renderProposalMarkdown defensively emit a terminal newline. Add focused regressions for the tool write path and markdown renderer. * fix(skill-workshop): reject blank raw proposal content * fix: treat empty-string optional integer tool params as unset Optional positive-integer tool params (e.g. Telegram replyTo/threadId) threw ToolInputError when a tool-calling model populated them with an empty-string or whitespace-only default. Those defaults carry no value, so readPositiveIntegerParam/readNonNegativeIntegerParam now treat a blank string as unset (undefined) instead of throwing, while still rejecting genuinely invalid present values (0, "42.5", "-3"). This prevents silent message-delivery failures when models emit empty routing-param defaults. Adds unit tests covering blank vs invalid. * fix(gateway): log start session persistence failures The gateway session-lifecycle "start" event persistence (persistGatewaySessionLifecycleEvent, which surfaces write failures via requireWriteSuccess) was fired as void ...catch(() => undefined), swallowing the rejection with zero logging. A failed start-marker write silently dropped the run's start record from restart-recovery accounting, with no operator-visible trace. The sibling terminal-phase catch already logs this since #97839; the start path was the unfixed sibling. Mirror that fix: log the swallowed start-phase persistence failure with the same redacted message shape via formatForLog, keeping the fire-and-forget semantics unchanged. Adds a focused regression test asserting the log fires on start-persist rejection. * fix(memory): report close-time pending work failures * fix(shared): return "" from sliceUtf16Safe when end <= start, matching native .slice sliceUtf16Safe silently swapped reversed bounds (to < from) instead of returning "" like String.prototype.slice, creating a subtle footgun for callers with dynamic start/end pairs. Caller scan across src/, extensions/, and packages/ confirmed no production code relies on the old swap behavior — all callers use (text, 0, N) or (text, -N) forms only. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(plugins): require plugin manifest in npm verifier * fix(android): propagate CancellationException in CameraHandler catch blocks Catch (err: Throwable) swallows kotlinx.coroutines.CancellationException, breaking structured concurrency when the coroutine scope is cancelled during camera operations (handleList/handleSnap/handleClip). Add CancellationException rethrow before each Throwable catch to match the existing pattern used in GatewaySession and TalkModeManager. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(android): propagate CancellationException past GatewaySession invoke boundary * chore: sync native i18n inventory after gateway session line shift * fix(agents): prevent native hook relay bridge race condition on renew and registration Remove synchronous bridge record write after server.listen() that races before the TCP server binds, and guard renew handler with server.listening check to prevent stale relay registrations. Closes #98650 * fix: harden small reliability fixes Co-authored-by: cxbAsDev <cxbAsDev@users.noreply.github.com> * docs(agents): explain buffered LSP spawn failures * docs(agents): clarify LSP spawn timeout invariant --------- Co-authored-by: qingminlong <qing.minlong@xydigit.com> Co-authored-by: anyech <anyech@gmail.com> Co-authored-by: snotty <snotty@users.noreply.github.com> Co-authored-by: masatohoshino <g515hoshino@gmail.com> Co-authored-by: lin-hongkuan <lin-hongkuan@users.noreply.github.com> Co-authored-by: simon-w <weng.qimeng@xydigit.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: 宇宙熊Yzx <53250620+849261680@users.noreply.github.com> Co-authored-by: xialonglee <li.xialong@xydigit.com> Co-authored-by: nankingjing <1079826437@qq.com> Co-authored-by: cxbAsDev <cxbAsDev@users.noreply.github.com> |
||
|
|
062f88e3e3 |
refactor: extract reusable AI runtime package (#99059)
* refactor: extract reusable AI runtime package * refactor: complete AI provider relocation * refactor: keep llm core internal * refactor(ai): make @openclaw/ai self-contained with host policy ports Move pure transport helpers (tool projections, strict-schema normalization, prompt-cache boundary, stream guards, anthropic/openai compat, request activity) from src into packages/ai; move utf16-slice into normalization-core. Inject host policy (guarded fetch, redaction, strict-tool defaults, diagnostics logging) through AiTransportHost with inert library defaults installed by src/llm/stream.ts. Narrow the public barrel to instance-scoped createApiRegistry/createLlmRuntime; the process-default runtime moves behind internal/ and registerBuiltInApiProviders takes an explicit registry. Delete the src/llm/api-registry re-export facade. * fix(ai): teach node, jiti, and vite resolvers the @openclaw/ai and utf16-slice subpaths The workspace alias tables in root-alias.cjs, plugin-sdk-native-resolver, sdk-alias, the shared vitest config, and the Control UI vite config only knew @openclaw/llm-core; Node-side plugin loading resolved @openclaw/ai through the pnpm symlink to the unbuilt dist (checks-node-compact CI failures), and the Control UI build broke on the new normalization-core/utf16-slice subpath. * chore(ui): drop leftover service-worker debug logging * build(release): ship @openclaw/ai with its own shrinkwrap and honest dependency set packages/ai declares only its six real runtime deps (kysely, chalk, json5, tslog, zod, fs-safe, and proxyline were never imported); orphaned root deps removed. generate-npm-shrinkwrap now treats publishable packages/* like publishable plugins so the AI tarball pins its transitive tree even though workspace deps are omitted from the root shrinkwrap. knip learns the package entry points; the tsdown dts neverBundle option moves to its documented deps.dts home; the README documents the no-semver internal/* contract and host ports. * docs(ai): add minimal external-consumer example app examples/ai-chat consumes only the public @openclaw/ai surface (built dist via the workspace link): isolated runtime, built-in provider registration, one streamed completion. Supports Anthropic/OpenAI via env keys and a keyless local Ollama target; live-verified against Ollama. * docs(ai): document the @openclaw/ai package and workspace shrinkwrap boundary * chore(check): include examples/ in duplicate-scan targets * fix: emit normalization package subpaths * fix: complete AI package boundary artifacts * fix: align AI package boundary contracts * fix(ci): stabilize package release contracts * test: align documentation contract checks * test: keep cron docs guard aligned * test: align restored docs contract guards * test: follow upstream docs contracts * docs: drop superseded talk wording |