Compare commits

...
2 Commits
Author SHA1 Message Date
brother7 3111dde5af fix: include prompt assets in standalone output 2026-08-19 21:55:43 +08:00
brother7 58d1ddc264 修改打包脚本 2026-08-18 23:45:32 +08:00
5 changed files with 181 additions and 1 deletions

No files matched your search

@@ -0,0 +1,94 @@
# Task: Diagnose Next.js production image build failure
## Identity
- Task ID: 20260818-next-build-7f3a
- Mode: Feature
- Branch: main
- Worktree: D:\Datas\OthersProjects\openmaic
- Base commit: a76c8d2613c6ab6e0c661fbfd574803c2b09fc44
- Owner: developer
- Status: Ready for integration
## Scope
- Diagnose the Jenkins/Docker failure at `OpenMAIC/Dockerfile:64` (`RUN pnpm build`).
- Reproduce the repository's production webpack build where the local environment permits,
and distinguish a source/build regression from a runner resource or timeout failure.
- Do not change application or Docker build behavior without the missing Jenkins/Docker
termination evidence.
## Intent And Constraints
- The supplied log stops after `Creating an optimized production build ...` and only shows
a bare `ELIFECYCLE Command failed`; it does not contain the terminating signal or compiler
diagnostic.
- The repository's `pnpm build` first requires the generated
`public/vendor/maic-importer/index.js`; the Docker dependency stage normally creates it via
postinstall, so a missing local copy must not be confused with the reported Docker failure.
- Preserve the clean source worktree; generated package dist files and `.next` output are
diagnostic artifacts only.
## Outcome
- The local Windows `pnpm build` initially stopped at the expected vendor guard because the
ignored postinstall artifact was absent. After generating ignored workspace dist outputs and
syncing the vendor bundle, the equivalent direct Next command completed successfully:
`node --max-old-space-size=8192 node_modules/next/dist/bin/next build --webpack`.
- The successful build compiled webpack in about 4.8 minutes, used roughly 5.7 GB working set
at peak sampling, then finished TypeScript, 56 static pages, traces, and standalone output.
- A second direct build with a 4096 MB V8 heap also completed successfully, but webpack took
about 5.4 minutes and the process used roughly 3.8–4.1 GB working set.
- The generated Next trace from the successful run records `run-webpack` at 326.806 seconds
and total `next-build` at 397.158 seconds; the trace and generated outputs were removed after
verification because they are ignored build artifacts.
- The middleware deprecation warning appeared in both successful builds and is not the failure.
- A subsequent Jenkins run again stopped at `#22 308.2` immediately after
`Creating an optimized production build ...`, with the same bare `ELIFECYCLE` and no
compiler/OOM diagnostic. The repeatable ~5-minute cutoff strengthens the external build-step
timeout hypothesis; it still does not identify the signal without Jenkins/Docker metadata.
- The evidence is consistent with a Jenkins/Docker memory ceiling or build-step timeout killing
webpack before it emits a compiler error. The exact external cause remains unverified because
the Docker daemon and Jenkins host logs are unavailable in this workspace.
- The build script in `OpenMAIC/package.json` now caps the V8 heap at 4096 MB instead of
8192 MB. This is a mitigation for the observed host-level memory pressure, not proof that
the external 5-minute termination was the sole cause.
## Verification
- `check_project_docs.py` passed.
- `task_context.py status --json` confirmed this task owns the clean main worktree.
- Direct Next webpack build with 8192 MB heap: passed, full route output and exit code 0.
- Direct Next webpack build with 4096 MB heap: passed, full route output and exit code 0.
- Read-only final diagnosis review: PASS; the reviewer agrees the evidence supports an
external timeout/resource termination hypothesis but cannot distinguish timeout from OOM.
- `git status --short --untracked-files=all`: only this task record remains untracked; temporary
generated source changes were restored.
- Docker daemon/engine is unavailable locally, so an end-to-end image build was not reproduced.
- Follow-up Jenkins log: same failure signature at approximately 308 seconds.
- The later diagnostic-script run ended with `ERROR: failed to solve: Canceled: context canceled`
and script exit code `124`; this is the script's own `timeout 900s`, not a compiler exit.
Its cgroup reported an effectively unlimited `memory.max` and `oom_kill 0`. The kernel output
contained a historical BuildKit Node OOM at 21:46:05 (about 6.3 GiB RSS), which proves the
7.3 GiB host has previously exhausted memory but is not timestamped to the 22:38 run.
- `OpenMAIC/package.json` parses successfully after the heap-cap change; `git diff --check`
reports no whitespace errors.
- Read-only implementation review: PASS; the reviewer found the one-line heap reduction and
proposed Jenkins observability/timeout wrapper consistent with the available evidence.
## Follow-ups
- Re-run Jenkins with untruncated output (`docker build --progress=plain`) and capture the final
30 lines plus the shell/Docker exit code.
- Check the build node/container memory limit (`/sys/fs/cgroup/memory.max`, `docker stats`, or
Jenkins host metrics) and whether the job has a five-minute command timeout. The repeated
~308-second cutoff makes that timeout the first check. Budget at least
6–8 GiB for this webpack build and a timeout above the observed ~6-minute end-to-end duration.
- Run the updated Jenkins command with `--progress=plain`, a 900-second per-image timeout, and
failure diagnostics for cgroup memory and kernel OOM evidence. Jenkins' own job timeout must
also exceed 15 minutes; a shell-level timeout cannot override a shorter Pipeline/plugin limit.
## Promotion Candidates
- None. This investigation does not establish a source or Docker configuration change without
the external termination signal.
@@ -0,0 +1,56 @@
# Task: Diagnose missing interactive outline prompt template
## Identity
- Task ID: 20260819-openmaic-prompt-template-8b4d
- Mode: Feature
- Branch: codex/20260819-openmaic-prompt-template-8b4d-openmaic-prompt-template
- Worktree: D:\w\omprompt-8b4d
- Base commit: 58d1ddc2644f4c8631d62eb0e5423365af95ef66
- Owner: codex
- Status: Ready-for-integration
## Scope
- Trace the production error `Interactive outline prompt template not found` from the classroom job runner to its runtime file dependency.
- Compare the runtime file path with the standalone Docker and learning-artifact packaging configuration.
- Provide a read-only Kubernetes check, implement the durable standalone packaging fix requested after diagnosis, and add a regression test.
## Intent And Constraints
- The user requested direct analysis without subagents.
- Preserve the existing dirty main worktree owned by `20260818-next-build-7f3a`; diagnosis ran in this isolated worktree at the same base commit.
- Distinguish source-level facts from the still-unverified contents of the deployed image.
- Keep the code change surgical: configure Next.js file tracing rather than duplicating copy rules across the Dockerfile and artifact builder.
## Outcome
- Confirmed that `lib/server/classroom-outline-mode.ts` raises the reported error only when the app prompt loader returns `null` for `interactive-outlines`.
- Confirmed that the loader reads Markdown dynamically from `<cwd>/lib/prompts/templates/<promptId>` and that both interactive-outline source files exist. Its broad catch also converts snippet-loading failures into the same outer error, while logging the original cause under `PromptLoader`.
- Confirmed that `interactive-outlines/system.md` includes three package-owned snippets (`image-instructions`, `video-instructions`, and `media-safety-guidelines`) that are dynamically read from `@openmaic/generation`.
- Confirmed that standalone output is enabled but `next.config.ts` has no `outputFileTracingIncludes`, while both the Docker runner and `build-learning-artifact.mjs` copy only standalone output, static assets, and public assets.
- Production root cause confirmed: the deployed Pod reports `ENOENT` for `/app/lib/prompts/templates/interactive-outlines/system.md`, and both `system.md` and `user.md` are absent while `cwd` is correctly `/app`. The standalone image omitted the app-owned prompt Markdown.
- A direct eval import of `@openmaic/generation` from `/app` also returned `ERR_MODULE_NOT_FOUND`. This is not the current first failure because template loading stops at the missing `system.md`; package snippet availability must be verified after the app templates are packaged, preferably through the built application or by inspecting the standalone trace/layout rather than assuming root-level package resolution.
- Added global standalone file-tracing includes for app-owned prompts, app PBL prompts, and the three package-owned generation prompt directories.
- Added `tests/config/standalone-prompt-assets.test.ts` to lock the runtime prompt asset contract.
## Verification
- Source template presence check: PASS (`system.md` and `user.md` exist).
- Packaging contract check: RED by design; source assets exist while neither file tracing includes nor an explicit runner copy is configured.
- Runtime path inspection: PASS (`WORKDIR /app` plus `process.cwd()/lib/prompts` resolves to `/app/lib/prompts`).
- Production Pod filesystem check: FAIL as expected; both interactive-outline files are missing from `/app` and the `PromptLoader` log records the exact `ENOENT` path.
- Targeted Vitest regression: PASS (1 test).
- ESLint on both changed product/test files: PASS.
- Prettier check on both changed product/test files: PASS.
- Learning-engine production build: webpack compilation PASS; final Next.js build FAILS on the pre-existing unrelated missing `@xmldom/xmldom` type declaration in `packages/@openmaic/importer/src/parser/XmlParser.ts`, before standalone output is emitted.
## Follow-ups
- Rebuild the image in an environment with the importer dependency installed, verify the prompt assets in the emitted standalone artifact, deploy, and rerun generation.
- Verify the package-owned snippets through a generation request; the root-level eval import is not a reliable proxy for bundled route resolution.
- Audit the other dynamically read app prompt directory `lib/pbl/v2/prompts` as part of the same packaging fix.
## Promotion Candidates
- None recorded.
+11
View File
@@ -10,6 +10,17 @@ const nextConfig: NextConfig = {
// default `.next`.
distDir: process.env.NEXT_DIST_DIR || '.next',
output: process.env.VERCEL ? undefined : 'standalone',
// Prompt loaders read Markdown dynamically at runtime, so Next.js cannot
// discover these assets from static imports when producing standalone output.
outputFileTracingIncludes: {
'/*': [
'./lib/prompts/**/*.md',
'./lib/pbl/v2/prompts/**/*.md',
'./packages/@openmaic/generation/templates/**/*.md',
'./packages/@openmaic/generation/snippets/**/*.md',
'./packages/@openmaic/generation/prompts-pbl/**/*.md',
],
},
...(basePath ? { basePath } : {}),
env: {
NEXT_PUBLIC_OPENMAIC_BASE_PATH: basePath,
+1 -1
View File
@@ -12,7 +12,7 @@
"gen:video-export-katex": "node scripts/generate-video-export-katex.mjs",
"gen:video-export-noto-cjk": "node scripts/generate-video-export-noto-cjk.mjs",
"dev": "next dev",
"build": "node scripts/assert-vendor-maic-importer.mjs && node --max-old-space-size=8192 node_modules/next/dist/bin/next build --webpack",
"build": "node scripts/assert-vendor-maic-importer.mjs && node --max-old-space-size=4096 node_modules/next/dist/bin/next build --webpack",
"build:learning-engine": "node scripts/build-learning-artifact.mjs engine",
"build:learning-ops": "node scripts/build-learning-artifact.mjs ops",
"build:makelore-player": "node scripts/build-learning-artifact.mjs player",
@@ -0,0 +1,19 @@
import { describe, expect, it } from 'vitest';
import nextConfig from '../../next.config';
const runtimePromptGlobs = [
'./lib/prompts/**/*.md',
'./lib/pbl/v2/prompts/**/*.md',
'./packages/@openmaic/generation/templates/**/*.md',
'./packages/@openmaic/generation/snippets/**/*.md',
'./packages/@openmaic/generation/prompts-pbl/**/*.md',
];
describe('standalone prompt assets', () => {
it('includes every dynamically loaded prompt directory in output file tracing', () => {
expect(nextConfig.outputFileTracingIncludes?.['/*']).toEqual(
expect.arrayContaining(runtimePromptGlobs),
);
});
});