@codio-ai/opencode-authoring-agent 0.1.5 → 0.1.7
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/agents/assessment-author.d.ts.map +1 -1
- package/dist/agents/orchestrator.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +243 -26
- package/dist/tools/create-assessment.d.ts +35 -2
- package/dist/tools/create-assessment.d.ts.map +1 -1
- package/dist/tools/create-page.d.ts +1 -1
- package/dist/tools/create-page.d.ts.map +1 -1
- package/dist/tools/fetch-course.d.ts +1 -1
- package/dist/tools/fetch-course.d.ts.map +1 -1
- package/dist/tools/index.d.ts +9 -6
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/publish-course.d.ts +1 -1
- package/dist/tools/publish-course.d.ts.map +1 -1
- package/dist/utils/taskid.d.ts +1 -1
- package/dist/utils/taskid.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/skills/reference-assessment-types/SKILL.md +109 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assessment-author.d.ts","sourceRoot":"","sources":["../../src/agents/assessment-author.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"assessment-author.d.ts","sourceRoot":"","sources":["../../src/agents/assessment-author.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA2C/C,wBAAgB,2BAA2B,CACzC,KAAK,CAAC,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,EACrB,kBAAkB,CAAC,EAAE,MAAM,GAC1B,eAAe,CAkBjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/agents/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAmD/C,wBAAgB,uBAAuB,CAAC,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/agents/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAmD/C,wBAAgB,uBAAuB,CAAC,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAoG5E;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,CAAC,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,EACrB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAC3B,eAAe,CAiBjB"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAUlD,QAAA,MAAM,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAUlD,QAAA,MAAM,oBAAoB,EA4FT,MAAM,CAAC;AAExB,eAAe,oBAAoB,CAAC;AAEpC,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -45788,13 +45788,13 @@ ${customAppendPrompt}`;
|
|
|
45788
45788
|
// src/agents/assessment-author.ts
|
|
45789
45789
|
var BASE_PROMPT = `# Assessment Author
|
|
45790
45790
|
|
|
45791
|
-
You author one or more assessments (MCQ, code test, fill-in-the-blanks, parsons-puzzle,
|
|
45791
|
+
You author one or more assessments (MCQ, code test, fill-in-the-blanks, parsons-puzzle, llm-based-auto-rubric, or probeable-question-act) for a Codio guide page. You return structured payloads. **You do not write JSON or files directly.** The orchestrator passes your payload to the \`create_assessment\` tool, which stamps the canonical JSON and writes it.
|
|
45792
45792
|
|
|
45793
45793
|
## Inputs
|
|
45794
45794
|
|
|
45795
|
-
- \`assessment_type\`: one of \`multiple-choice\`, \`code-output-compare\`, \`fill-in-the-blanks\`, \`parsons-puzzle\`, \`llm-based-auto-rubric\`.
|
|
45795
|
+
- \`assessment_type\`: one of \`multiple-choice\`, \`code-output-compare\`, \`fill-in-the-blanks\`, \`parsons-puzzle\`, \`llm-based-auto-rubric\`, \`probeable-question-act\`.
|
|
45796
45796
|
- \`topic\`, \`lo\` (learning objective), \`page_context\` (the page body for grounding).
|
|
45797
|
-
- \`count\` (how many to author; default 1 for code-test/FITB/parsons/auto-rubric, 3 for MCQ).
|
|
45797
|
+
- \`count\` (how many to author; default 1 for code-test/FITB/parsons/auto-rubric/probeable, 3 for MCQ).
|
|
45798
45798
|
|
|
45799
45799
|
## Output
|
|
45800
45800
|
|
|
@@ -45807,6 +45807,16 @@ Return one payload per assessment, in the exact shape \`create_assessment\` expe
|
|
|
45807
45807
|
- For \`fill-in-the-blanks\`: use the \`<<<answer>>>\` marker syntax inline in the \`text\` field. Each blank should test one concrete piece of recall or application.
|
|
45808
45808
|
- For \`parsons-puzzle\`: provide a correct code solution as \`initial\`, then append distractor lines below — each distractor labeled with a \`#distractor\` comment so the orchestrator can review. Aim for 2–4 distractors that reflect common syntactic or logical mistakes (off-by-one, wrong operator, wrong variable name). Indent matters for Python — call out which indent levels each block needs.
|
|
45809
45809
|
- For \`llm-based-auto-rubric\`: write 3–5 rubric items, each scoped to one observable dimension (syntax, logic, edge cases, style). Each item has a clear \`title\` and a \`description\` written for the LLM grader to apply (concrete criteria, not vague). Always include a \`solutions\` array under \`.guides/secure/\` so the grader has reference; never expose solution paths under \`.guides/content/\`.
|
|
45810
|
+
- For \`probeable-question-act\`: collect these fields before returning the payload:
|
|
45811
|
+
- \`functionName\` — Python function name (snake_case), used as the file stem.
|
|
45812
|
+
- \`functionSignature\` — full def line with type hints, e.g. \`def min_index(int_list: list[int]) -> int:\`
|
|
45813
|
+
- \`problemStatement\` — narrative description of what the function must do.
|
|
45814
|
+
- \`inputVariable\` — the variable students modify to probe, e.g. \`int_list\`.
|
|
45815
|
+
- \`inputVariableAnnotation\` — Python type annotation, e.g. \`list[int]\`.
|
|
45816
|
+
- \`defaultInputValue\` — default value shown in the student file, e.g. \`[1, 2, 3]\`.
|
|
45817
|
+
- \`referenceSolution\` — the complete working function definition (including the \`def\` line and body).
|
|
45818
|
+
- \`unitTests\` — full Python unittest file content.
|
|
45819
|
+
**If the instructor has not provided \`referenceSolution\` or \`unitTests\`, ask whether they want to supply them or have you generate them. Generate only if the instructor explicitly says to.**
|
|
45810
45820
|
|
|
45811
45821
|
## What you don't do
|
|
45812
45822
|
|
|
@@ -45819,7 +45829,7 @@ function createAssessmentAuthorAgent(model, customPrompt, customAppendPrompt) {
|
|
|
45819
45829
|
const prompt = resolvePrompt(BASE_PROMPT, customPrompt, customAppendPrompt);
|
|
45820
45830
|
return {
|
|
45821
45831
|
name: "assessment-author",
|
|
45822
|
-
description: "Authors MCQ / code-output-compare / fill-in-the-blanks / parsons-puzzle / llm-based-auto-rubric payloads. Returns structured payloads; does not write files.",
|
|
45832
|
+
description: "Authors MCQ / code-output-compare / fill-in-the-blanks / parsons-puzzle / llm-based-auto-rubric / probeable-question-act payloads. Returns structured payloads; does not write files.",
|
|
45823
45833
|
config: {
|
|
45824
45834
|
mode: "subagent",
|
|
45825
45835
|
model,
|
|
@@ -45854,11 +45864,11 @@ var AGENT_DESCRIPTIONS = {
|
|
|
45854
45864
|
- **Rule of thumb:** New prose or non-trivial edit → @page-author. Trivial fix → yourself.
|
|
45855
45865
|
- **layoutConfig:** When delegating, include \`layoutConfig: { openFiles: string[] }\` derived from the page's \`files\` list so @page-author can generate adaptive file instructions.`,
|
|
45856
45866
|
"assessment-author": `@assessment-author
|
|
45857
|
-
- Role: Authors MCQ / code-output-compare / fill-in-the-blanks / parsons-puzzle / llm-based-auto-rubric payloads. Returns structured payloads only.
|
|
45867
|
+
- Role: Authors MCQ / code-output-compare / fill-in-the-blanks / parsons-puzzle / llm-based-auto-rubric / probeable-question-act payloads. Returns structured payloads only.
|
|
45858
45868
|
- Permissions: Read only
|
|
45859
45869
|
- Stats: Pedagogy + distractor quality is the hardest content judgment in this system. Sonnet-class.
|
|
45860
|
-
- Capabilities: MCQ pedagogy, code-test design, FITB construction, Parsons distractor design, LLM rubric authoring.
|
|
45861
|
-
- **Delegate when:** Authoring any new assessment (multiple-choice, code-output-compare, fill-in-the-blanks, parsons-puzzle, llm-based-auto-rubric).
|
|
45870
|
+
- Capabilities: MCQ pedagogy, code-test design, FITB construction, Parsons distractor design, LLM rubric authoring, probeable question design.
|
|
45871
|
+
- **Delegate when:** Authoring any new assessment (multiple-choice, code-output-compare, fill-in-the-blanks, parsons-puzzle, llm-based-auto-rubric, probeable-question-act).
|
|
45862
45872
|
- **Don't delegate when:** Re-running create_assessment with the same payload (no LLM work needed).
|
|
45863
45873
|
- **Rule of thumb:** New question content → @assessment-author. Re-stamp existing payload → tool only.`,
|
|
45864
45874
|
"source-ingester": `@source-ingester
|
|
@@ -45909,12 +45919,12 @@ ${enabledAgents}
|
|
|
45909
45919
|
|
|
45910
45920
|
### Authoring tools
|
|
45911
45921
|
- \`create_page({workspace, stem, title, type, layout, learningObjectives, files?, markdownBody, chapterFolder?})\` — stamp a page JSON with a fresh v4 UUID and write the JSON+MD pair. Use after \`@page-author\` returns a body+metadata in draft mode. Validates freeze directive syntax before writing — will throw if FREEZE CODE BEGIN/END are unmatched or use wrong comment prefix for the language.
|
|
45912
|
-
- \`create_assessment({type, workspace, payload})\` — stamp an assessment JSON with a fresh taskId and write to \`.guides/assessments/\`. Returns \`{ taskId, jsonPath, embedLine }
|
|
45922
|
+
- \`create_assessment({type, workspace, payload})\` — stamp an assessment JSON with a fresh taskId and write to \`.guides/assessments/\`. Returns \`{ taskId, jsonPath, embedLine }\` for standard types. For \`probeable-question-act\` also returns \`{ studentFilePath, probeScriptPath, probeButtonCommand, runButtonCommand, suggestedPageMarkdown }\` and writes 3 additional files (student file, probe script, unit test file). Use \`suggestedPageMarkdown\` as the body_brief for \`@page-author\` when creating the guide page for a probeable question.
|
|
45913
45923
|
- \`validate_guide({workspace})\` — deterministic structural validation (UUIDs, order arrays, embed references, taskId/filename consistency). Run automatically at the end of new-assignment, import-source, and reorder workflows. Run manually on user request (\`/validate-guide\`).
|
|
45914
45924
|
|
|
45915
45925
|
### Codio platform tools
|
|
45916
|
-
- \`fetch_course({
|
|
45917
|
-
- \`publish_course({
|
|
45926
|
+
- \`fetch_course({courseId, workspace?, outputDir?, domain?})\` — pull an existing Codio course from the platform into an AI-ready local project. Requires \`CODIO_CLIENT_ID\` and \`CODIO_CLIENT_SECRET\` env vars. Returns \`{ outputDir, manifestPath, moduleCount, assignmentCount }\`. Writes \`course-manifest.json\`, \`course-assignments.csv\`, and extracted assignment content under \`course-content/\`. **Delegate when:** user wants to fetch, pull, import, or export an existing Codio course.
|
|
45927
|
+
- \`publish_course({manifestPath, workspace?, dryRun?, force?, module?, assignment?, changelog?, stack?})\` — push course assignments back to the Codio platform using \`course-manifest.json\` as the source of truth. Creates missing courses/modules/assignments automatically. Skips unchanged assignments by content hash. Returns \`{ published, created, unchanged, skipped }\`. **Delegate when:** user wants to publish, push, deploy, or sync assignments to Codio. Always suggest \`dryRun: true\` first to preview.
|
|
45918
45928
|
|
|
45919
45929
|
### Platform tool routing
|
|
45920
45930
|
- User says "fetch/pull/import/export this course" → \`fetch_course\`
|
|
@@ -45942,7 +45952,8 @@ Only fan out where work is independent — page drafting (Phase 4) and assessmen
|
|
|
45942
45952
|
|
|
45943
45953
|
- New page JSON+MD pair → \`@page-author\` (draft mode) returns body+metadata → you call \`create_page\`. **Do not** hand-write the JSON.
|
|
45944
45954
|
- Existing page surgical edit → \`@page-author\` (revise mode) edits the .md directly. No tool call.
|
|
45945
|
-
- New assessment → \`@assessment-author\` returns payload → you call \`create_assessment\` → you splice the returned \`embedLine\` into the page.
|
|
45955
|
+
- New standard assessment → \`@assessment-author\` returns payload → you call \`create_assessment\` → you splice the returned \`embedLine\` into the page.
|
|
45956
|
+
- New probeable question → \`@assessment-author\` returns payload → you call \`create_assessment\` (type: probeable-question-act) → use \`suggestedPageMarkdown\` as body_brief for \`@page-author\` → call \`create_page\`.
|
|
45946
45957
|
- \`order\` array updates → you edit the index.json yourself with the edit tool. Small contextual JSON; no tool needed.
|
|
45947
45958
|
- Stem generation (kebab-slug + 4-hex) → you generate inline. No tool.
|
|
45948
45959
|
</Workflow>
|
|
@@ -46455,14 +46466,20 @@ var ASSESSMENT_TYPES = [
|
|
|
46455
46466
|
"code-output-compare",
|
|
46456
46467
|
"fill-in-the-blanks",
|
|
46457
46468
|
"parsons-puzzle",
|
|
46458
|
-
"llm-based-auto-rubric"
|
|
46469
|
+
"llm-based-auto-rubric",
|
|
46470
|
+
"probeable-question-act"
|
|
46459
46471
|
];
|
|
46460
|
-
var
|
|
46461
|
-
|
|
46472
|
+
var TASKID_PREFIX = {
|
|
46473
|
+
"probeable-question-act": "test"
|
|
46474
|
+
};
|
|
46475
|
+
var ALL_PREFIXES = [...new Set(ASSESSMENT_TYPES.map((t) => TASKID_PREFIX[t] ?? t))];
|
|
46476
|
+
var TASKID_RE = new RegExp(`^(${ALL_PREFIXES.join("|")})-[1-9][0-9]{9}$`);
|
|
46477
|
+
var ANY_TASKID_RE = new RegExp(`(?:${ALL_PREFIXES.join("|")})-[1-9][0-9]{9}`, "g");
|
|
46462
46478
|
function generateTaskId(type) {
|
|
46479
|
+
const prefix = TASKID_PREFIX[type] ?? type;
|
|
46463
46480
|
const first = randomInt(1, 10);
|
|
46464
46481
|
const rest = randomInt(0, 1e9).toString().padStart(9, "0");
|
|
46465
|
-
return `${
|
|
46482
|
+
return `${prefix}-${first}${rest}`;
|
|
46466
46483
|
}
|
|
46467
46484
|
|
|
46468
46485
|
// src/utils/uuid.ts
|
|
@@ -46481,7 +46498,8 @@ var ASSESSMENT_TYPE_TAG = {
|
|
|
46481
46498
|
"code-output-compare": "Standard Code Test",
|
|
46482
46499
|
"fill-in-the-blanks": "Fill in the Blanks",
|
|
46483
46500
|
"parsons-puzzle": "Parsons Puzzle",
|
|
46484
|
-
"llm-based-auto-rubric": null
|
|
46501
|
+
"llm-based-auto-rubric": null,
|
|
46502
|
+
"probeable-question-act": "Advanced Code Test"
|
|
46485
46503
|
};
|
|
46486
46504
|
function ensureAssessmentTag(tags, type) {
|
|
46487
46505
|
const list = tags ? [...tags] : [];
|
|
@@ -46808,6 +46826,170 @@ function buildLlmAutoRubricAssessment(raw, taskId = generateTaskId("llm-based-au
|
|
|
46808
46826
|
}
|
|
46809
46827
|
};
|
|
46810
46828
|
}
|
|
46829
|
+
var probeablePayloadSchema = z2.object({
|
|
46830
|
+
functionName: z2.string().min(1),
|
|
46831
|
+
functionSignature: z2.string().min(1),
|
|
46832
|
+
problemStatement: z2.string().min(1),
|
|
46833
|
+
inputVariable: z2.string().min(1),
|
|
46834
|
+
inputVariableAnnotation: z2.string().min(1),
|
|
46835
|
+
defaultInputValue: z2.string().min(1),
|
|
46836
|
+
referenceSolution: z2.string().min(1),
|
|
46837
|
+
unitTests: z2.string().min(1),
|
|
46838
|
+
name: z2.string().optional(),
|
|
46839
|
+
points: z2.number().int().nonnegative().default(20),
|
|
46840
|
+
maxAttemptsCount: z2.number().int().nonnegative().default(0),
|
|
46841
|
+
timeoutSeconds: z2.number().int().positive().default(40),
|
|
46842
|
+
guidance: z2.string().default(""),
|
|
46843
|
+
lo: z2.string().default(""),
|
|
46844
|
+
blooms: z2.string().default("")
|
|
46845
|
+
});
|
|
46846
|
+
function indentLines(text, spaces) {
|
|
46847
|
+
const pad = " ".repeat(spaces);
|
|
46848
|
+
return text.split(`
|
|
46849
|
+
`).map((line) => line.trim() ? pad + line : line).join(`
|
|
46850
|
+
`);
|
|
46851
|
+
}
|
|
46852
|
+
function buildProbeableAssessment(raw, taskId, workspace) {
|
|
46853
|
+
const p = probeablePayloadSchema.parse(raw);
|
|
46854
|
+
const fn = p.functionName;
|
|
46855
|
+
const studentFilePath = `code/functions/probeable_${fn}.py`;
|
|
46856
|
+
const probeScriptPath = `.guides/probeable_questions/probe_${fn}.py`;
|
|
46857
|
+
const unitTestPath = `.guides/secure/unit_tests/probeable_questions/${fn}_test.py`;
|
|
46858
|
+
const studentFileContent = [
|
|
46859
|
+
`# Probe ${fn}: Modify only the ${p.inputVariable} values to test edge cases`,
|
|
46860
|
+
``,
|
|
46861
|
+
`${p.inputVariable}: ${p.inputVariableAnnotation} = ${p.defaultInputValue}`,
|
|
46862
|
+
``,
|
|
46863
|
+
`${p.functionSignature}`,
|
|
46864
|
+
` # Replace 'pass' with your solution`,
|
|
46865
|
+
` pass`,
|
|
46866
|
+
``,
|
|
46867
|
+
``,
|
|
46868
|
+
``,
|
|
46869
|
+
`# FREEZE CODE BEGIN`,
|
|
46870
|
+
`if __name__=="__main__":`,
|
|
46871
|
+
` print(f"${p.inputVariable} = {${p.inputVariable}} , result = {${fn}(${p.inputVariable})}")`,
|
|
46872
|
+
`# FREEZE CODE END`
|
|
46873
|
+
].join(`
|
|
46874
|
+
`);
|
|
46875
|
+
const indentedSolution = indentLines(p.referenceSolution.trimEnd(), 4);
|
|
46876
|
+
const moduleName = `probeable_${fn}`;
|
|
46877
|
+
const logFile = `${workspace}/code/functions/probeable_${fn}_io_logs.txt`;
|
|
46878
|
+
const probeScriptContent = [
|
|
46879
|
+
`import sys`,
|
|
46880
|
+
`sys.path.append("${workspace}/code/functions/")`,
|
|
46881
|
+
``,
|
|
46882
|
+
`class MissingVariableError(Exception):`,
|
|
46883
|
+
` def __str__(self):`,
|
|
46884
|
+
` return "Error: The required '${p.inputVariable}' variable is missing. Please declare '${p.inputVariable}' as a ${p.inputVariableAnnotation}."`,
|
|
46885
|
+
``,
|
|
46886
|
+
``,
|
|
46887
|
+
`def check_import_and_probe():`,
|
|
46888
|
+
` try:`,
|
|
46889
|
+
` from ${moduleName} import ${p.inputVariable}`,
|
|
46890
|
+
``,
|
|
46891
|
+
`${indentedSolution}`,
|
|
46892
|
+
``,
|
|
46893
|
+
` if __name__ == "__main__":`,
|
|
46894
|
+
` log_file = "${logFile}"`,
|
|
46895
|
+
` result = ${fn}(${p.inputVariable})`,
|
|
46896
|
+
` with open(log_file, "a") as f:`,
|
|
46897
|
+
` f.write(f"${p.inputVariable} = {${p.inputVariable}} , result = {result}\\n")`,
|
|
46898
|
+
` with open(log_file, "r") as f:`,
|
|
46899
|
+
` for line in f.readlines():`,
|
|
46900
|
+
` print(line)`,
|
|
46901
|
+
``,
|
|
46902
|
+
` except ImportError:`,
|
|
46903
|
+
` raise MissingVariableError()`,
|
|
46904
|
+
`try:`,
|
|
46905
|
+
` check_import_and_probe()`,
|
|
46906
|
+
`except MissingVariableError as e:`,
|
|
46907
|
+
` print(e)`,
|
|
46908
|
+
` sys.exit(1)`
|
|
46909
|
+
].join(`
|
|
46910
|
+
`);
|
|
46911
|
+
const codeEnvConfig = JSON.stringify({
|
|
46912
|
+
type: "python",
|
|
46913
|
+
subtype: "unittest",
|
|
46914
|
+
files: [unitTestPath],
|
|
46915
|
+
maxPoints: p.points,
|
|
46916
|
+
timeout: p.timeoutSeconds,
|
|
46917
|
+
executable: "python3",
|
|
46918
|
+
pythonwd: ".guides/secure/unit_tests/probeable_questions",
|
|
46919
|
+
partialPoints: false
|
|
46920
|
+
});
|
|
46921
|
+
const assessmentJson = {
|
|
46922
|
+
type: "test",
|
|
46923
|
+
taskId,
|
|
46924
|
+
source: {
|
|
46925
|
+
name: p.name ?? fn,
|
|
46926
|
+
showName: false,
|
|
46927
|
+
instructions: "**Submit your work for evaluation**",
|
|
46928
|
+
command: "python /usr/share/codio/assessments/assessments.py",
|
|
46929
|
+
codeEnvConfig,
|
|
46930
|
+
pythonPath: join3(workspace, "code", "functions"),
|
|
46931
|
+
timeoutSeconds: p.timeoutSeconds,
|
|
46932
|
+
guidance: p.guidance,
|
|
46933
|
+
showGuidanceAfterResponseOption: { type: "Never" },
|
|
46934
|
+
maxAttemptsCount: p.maxAttemptsCount,
|
|
46935
|
+
points: p.points,
|
|
46936
|
+
arePartialPointsAllowed: false,
|
|
46937
|
+
useMaximumScore: false,
|
|
46938
|
+
metadata: {
|
|
46939
|
+
tags: [{ name: "Assessment Type", value: "Advanced Code Test" }],
|
|
46940
|
+
files: [studentFilePath],
|
|
46941
|
+
opened: [{ type: "file", panelNumber: 0, content: studentFilePath }]
|
|
46942
|
+
},
|
|
46943
|
+
bloomsObjectiveLevel: p.blooms,
|
|
46944
|
+
learningObjectives: p.lo
|
|
46945
|
+
}
|
|
46946
|
+
};
|
|
46947
|
+
const probeButtonCommand = `python3 ${probeScriptPath}`;
|
|
46948
|
+
const runButtonCommand = `python3 ${studentFilePath}`;
|
|
46949
|
+
const embedLine = `{Check It!|assessment}(${taskId})`;
|
|
46950
|
+
const suggestedPageMarkdown = [
|
|
46951
|
+
`${p.problemStatement}`,
|
|
46952
|
+
``,
|
|
46953
|
+
`#### Probing the solution to find edge cases`,
|
|
46954
|
+
``,
|
|
46955
|
+
`You have the ability to 'probe' the solution. Modify the values in \`${p.inputVariable}\` to check the *expected* return value and discover edge cases. You will see the results of all your inputs.`,
|
|
46956
|
+
``,
|
|
46957
|
+
`|||warning`,
|
|
46958
|
+
`## \`${fn}\` code`,
|
|
46959
|
+
``,
|
|
46960
|
+
`Probing the solution will run the code in the editor. If the code in your file has syntax errors, probing will not work.`,
|
|
46961
|
+
``,
|
|
46962
|
+
`Pro-tip: Leave only the \`pass\` keyword in the \`${fn}\` function while probing.`,
|
|
46963
|
+
`|||`,
|
|
46964
|
+
``,
|
|
46965
|
+
`{Probe Solution}(${probeButtonCommand})`,
|
|
46966
|
+
``,
|
|
46967
|
+
``,
|
|
46968
|
+
`## Complete the function`,
|
|
46969
|
+
``,
|
|
46970
|
+
`Now that you have probed the solution, write your code and complete the \`${fn}\` function.`,
|
|
46971
|
+
``,
|
|
46972
|
+
`{Run it !}(${runButtonCommand})`,
|
|
46973
|
+
``,
|
|
46974
|
+
`${embedLine}`
|
|
46975
|
+
].join(`
|
|
46976
|
+
`);
|
|
46977
|
+
return {
|
|
46978
|
+
taskId,
|
|
46979
|
+
jsonPath: "",
|
|
46980
|
+
embedLine,
|
|
46981
|
+
studentFilePath,
|
|
46982
|
+
probeScriptPath,
|
|
46983
|
+
unitTestPath,
|
|
46984
|
+
probeButtonCommand,
|
|
46985
|
+
runButtonCommand,
|
|
46986
|
+
suggestedPageMarkdown,
|
|
46987
|
+
json: assessmentJson,
|
|
46988
|
+
studentFileContent,
|
|
46989
|
+
probeScriptContent,
|
|
46990
|
+
unitTestContent: p.unitTests
|
|
46991
|
+
};
|
|
46992
|
+
}
|
|
46811
46993
|
var createAssessmentInputSchema = z2.discriminatedUnion("type", [
|
|
46812
46994
|
z2.object({
|
|
46813
46995
|
type: z2.literal("multiple-choice"),
|
|
@@ -46833,6 +47015,11 @@ var createAssessmentInputSchema = z2.discriminatedUnion("type", [
|
|
|
46833
47015
|
type: z2.literal("llm-based-auto-rubric"),
|
|
46834
47016
|
workspace: z2.string().min(1),
|
|
46835
47017
|
payload: z2.unknown()
|
|
47018
|
+
}),
|
|
47019
|
+
z2.object({
|
|
47020
|
+
type: z2.literal("probeable-question-act"),
|
|
47021
|
+
workspace: z2.string().min(1),
|
|
47022
|
+
payload: z2.unknown()
|
|
46836
47023
|
})
|
|
46837
47024
|
]);
|
|
46838
47025
|
async function createAssessmentHandler(raw) {
|
|
@@ -46873,6 +47060,28 @@ async function createAssessmentHandler(raw) {
|
|
|
46873
47060
|
name = json.source.name || taskId;
|
|
46874
47061
|
const parsed = llmAutoRubricPayloadSchema.parse(input.payload);
|
|
46875
47062
|
llmSolutions = parsed.solutions;
|
|
47063
|
+
} else if (input.type === "probeable-question-act") {
|
|
47064
|
+
const taskId = generateTaskId("probeable-question-act");
|
|
47065
|
+
const built = buildProbeableAssessment(input.payload, taskId, workspace);
|
|
47066
|
+
const jsonPath2 = join3(assessments, `${taskId}.json`);
|
|
47067
|
+
try {
|
|
47068
|
+
writeFileSync(jsonPath2, `${JSON.stringify(built.json, null, 2)}
|
|
47069
|
+
`, { flag: "wx" });
|
|
47070
|
+
} catch (err) {
|
|
47071
|
+
if (err.code === "EEXIST")
|
|
47072
|
+
throw new Error(`taskId collision at ${jsonPath2}`);
|
|
47073
|
+
throw err;
|
|
47074
|
+
}
|
|
47075
|
+
const studentAbs = join3(workspace, built.studentFilePath);
|
|
47076
|
+
mkdirSync(dirname(studentAbs), { recursive: true });
|
|
47077
|
+
writeFileSync(studentAbs, built.studentFileContent, { flag: "wx" });
|
|
47078
|
+
const probeAbs = join3(workspace, built.probeScriptPath);
|
|
47079
|
+
mkdirSync(dirname(probeAbs), { recursive: true });
|
|
47080
|
+
writeFileSync(probeAbs, built.probeScriptContent, { flag: "wx" });
|
|
47081
|
+
const unitTestAbs = join3(workspace, built.unitTestPath);
|
|
47082
|
+
mkdirSync(dirname(unitTestAbs), { recursive: true });
|
|
47083
|
+
writeFileSync(unitTestAbs, built.unitTestContent, { flag: "wx" });
|
|
47084
|
+
return { ...built, jsonPath: jsonPath2 };
|
|
46876
47085
|
} else {
|
|
46877
47086
|
throw new Error(`unsupported assessment type: ${input.type}`);
|
|
46878
47087
|
}
|
|
@@ -46973,7 +47182,7 @@ var createPageInputSchema = z3.object({
|
|
|
46973
47182
|
type: z3.enum(PAGE_TYPES),
|
|
46974
47183
|
layout: z3.enum(PAGE_LAYOUTS),
|
|
46975
47184
|
learningObjectives: z3.array(z3.string()).default([]),
|
|
46976
|
-
files: z3.array(z3.string()).optional(),
|
|
47185
|
+
files: z3.preprocess((v) => Array.isArray(v) ? v.map((f) => typeof f === "string" ? f : typeof f === "object" && f !== null && ("path" in f) ? String(f.path) : f) : v, z3.array(z3.string()).optional()),
|
|
46977
47186
|
markdownBody: z3.string(),
|
|
46978
47187
|
chapterFolder: z3.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "chapterFolder must be a kebab-case directory name (no slashes, no ..)").optional()
|
|
46979
47188
|
}).refine((v) => v.layout !== "2-panels-tree" || v.files && v.files.length > 0, { message: "layout=2-panels-tree requires files", path: ["files"] });
|
|
@@ -47080,7 +47289,7 @@ function loadEnvWalkUp(startDir) {
|
|
|
47080
47289
|
// src/tools/fetch-course.ts
|
|
47081
47290
|
var execFileAsync = promisify(execFile);
|
|
47082
47291
|
var fetchCourseInputSchema = z4.object({
|
|
47083
|
-
workspace: z4.string().
|
|
47292
|
+
workspace: z4.string().optional().describe("Absolute path to the Codio workspace root (defaults to current working directory)"),
|
|
47084
47293
|
courseId: z4.string().min(1).describe("Codio course ID (32-char hex)"),
|
|
47085
47294
|
outputDir: z4.string().optional().describe("Output folder name inside workspace (default: course-project)"),
|
|
47086
47295
|
domain: z4.string().optional().describe("Codio domain (default: codio.com)")
|
|
@@ -47135,7 +47344,8 @@ function copyDir(src, dst) {
|
|
|
47135
47344
|
}
|
|
47136
47345
|
async function fetchCourseHandler(raw) {
|
|
47137
47346
|
const input = fetchCourseInputSchema.parse(raw);
|
|
47138
|
-
|
|
47347
|
+
const workspace = input.workspace?.trim() || process.cwd();
|
|
47348
|
+
loadEnvWalkUp(workspace);
|
|
47139
47349
|
const [{ default: codio }, { json2csv }] = await Promise.all([
|
|
47140
47350
|
Promise.resolve().then(() => __toESM(require_lib3(), 1)),
|
|
47141
47351
|
Promise.resolve().then(() => __toESM(require_converter(), 1))
|
|
@@ -47147,7 +47357,7 @@ async function fetchCourseHandler(raw) {
|
|
|
47147
47357
|
}
|
|
47148
47358
|
const domain = input.domain ?? process.env["CODIO_DOMAIN"] ?? "codio.com";
|
|
47149
47359
|
const outputFolderName = input.outputDir ?? "course-project";
|
|
47150
|
-
const outputDir = join6(
|
|
47360
|
+
const outputDir = join6(workspace, outputFolderName);
|
|
47151
47361
|
const contentDir = join6(outputDir, "course-content");
|
|
47152
47362
|
const manifestPath = join6(outputDir, "course-manifest.json");
|
|
47153
47363
|
const csvPath = join6(outputDir, "course-assignments.csv");
|
|
@@ -47201,7 +47411,7 @@ async function fetchCourseHandler(raw) {
|
|
|
47201
47411
|
assignmentFolder: a.folder,
|
|
47202
47412
|
assignmentPath: a.path
|
|
47203
47413
|
})));
|
|
47204
|
-
const csv =
|
|
47414
|
+
const csv = json2csv(rows, { emptyFieldValue: "", prependHeader: true });
|
|
47205
47415
|
await writeFile(csvPath, csv, "utf8");
|
|
47206
47416
|
const workDir = join6(tmpdir(), `codio-fetch-${Date.now()}`);
|
|
47207
47417
|
const zipPath = join6(workDir, "course-export.zip");
|
|
@@ -47237,7 +47447,7 @@ import { join as join7, relative } from "node:path";
|
|
|
47237
47447
|
import { z as z5 } from "zod";
|
|
47238
47448
|
var DEFAULT_STACK = "e0195698-d647-4490-8834-350583b532eb:latest";
|
|
47239
47449
|
var publishCourseInputSchema = z5.object({
|
|
47240
|
-
workspace: z5.string().
|
|
47450
|
+
workspace: z5.string().optional().describe("Absolute path to the Codio workspace root where .env lives (defaults to current working directory)"),
|
|
47241
47451
|
manifestPath: z5.string().min(1).describe("Absolute path to course-manifest.json"),
|
|
47242
47452
|
dryRun: z5.boolean().optional().describe("Preview actions without making changes"),
|
|
47243
47453
|
force: z5.boolean().optional().describe("Publish all, bypassing change detection"),
|
|
@@ -47282,7 +47492,8 @@ function computeContentHash(dir) {
|
|
|
47282
47492
|
}
|
|
47283
47493
|
async function publishCourseHandler(raw) {
|
|
47284
47494
|
const input = publishCourseInputSchema.parse(raw);
|
|
47285
|
-
|
|
47495
|
+
const workspace = input.workspace?.trim() || process.cwd();
|
|
47496
|
+
loadEnvWalkUp(workspace);
|
|
47286
47497
|
const { default: codio } = await Promise.resolve().then(() => __toESM(require_lib3(), 1));
|
|
47287
47498
|
const clientId = process.env["CODIO_CLIENT_ID"];
|
|
47288
47499
|
const clientSecret = process.env["CODIO_CLIENT_SECRET"];
|
|
@@ -47673,9 +47884,9 @@ var create_page = tool({
|
|
|
47673
47884
|
}
|
|
47674
47885
|
});
|
|
47675
47886
|
var create_assessment = tool({
|
|
47676
|
-
description: "Create a Codio assessment
|
|
47887
|
+
description: "Create a Codio assessment. Type options: multiple-choice, code-output-compare, fill-in-the-blanks, parsons-puzzle, llm-based-auto-rubric, probeable-question-act. Returns { taskId, jsonPath, embedLine } for standard types. For probeable-question-act also returns { studentFilePath, probeScriptPath, probeButtonCommand, runButtonCommand, suggestedPageMarkdown } and writes student file, probe script, and unit test file.",
|
|
47677
47888
|
args: {
|
|
47678
|
-
type: tool.schema.enum(["multiple-choice", "code-output-compare", "fill-in-the-blanks"]).describe("Assessment type"),
|
|
47889
|
+
type: tool.schema.enum(["multiple-choice", "code-output-compare", "fill-in-the-blanks", "parsons-puzzle", "llm-based-auto-rubric", "probeable-question-act"]).describe("Assessment type"),
|
|
47679
47890
|
workspace: tool.schema.string().min(1).describe("Absolute path to the Codio workspace root"),
|
|
47680
47891
|
payload: tool.schema.unknown().describe("Assessment payload object (type-specific fields)")
|
|
47681
47892
|
},
|
|
@@ -47768,7 +47979,13 @@ var CodioAuthoringPlugin = async (ctx) => {
|
|
|
47768
47979
|
return;
|
|
47769
47980
|
const orchestratorDef = agentDefs.find((a) => a.name === "codio-orchestrator");
|
|
47770
47981
|
const orchestratorPrompt = typeof orchestratorDef?.config?.prompt === "string" ? orchestratorDef.config.prompt : buildOrchestratorPrompt(disabledAgents);
|
|
47771
|
-
|
|
47982
|
+
const workspaceBlock = `<Workspace>
|
|
47983
|
+
Workspace root: ${ctx.directory}
|
|
47984
|
+
Always pass this exact path as the \`workspace\` argument to all tools.
|
|
47985
|
+
</Workspace>`;
|
|
47986
|
+
output.system[0] = orchestratorPrompt + `
|
|
47987
|
+
|
|
47988
|
+
${workspaceBlock}` + (output.system[0] ? `
|
|
47772
47989
|
|
|
47773
47990
|
${output.system[0]}` : "");
|
|
47774
47991
|
}
|
|
@@ -279,6 +279,35 @@ export interface LlmAutoRubricAssessmentJson {
|
|
|
279
279
|
};
|
|
280
280
|
}
|
|
281
281
|
export declare function buildLlmAutoRubricAssessment(raw: unknown, taskId?: string): LlmAutoRubricAssessmentJson;
|
|
282
|
+
export declare const probeablePayloadSchema: z.ZodObject<{
|
|
283
|
+
functionName: z.ZodString;
|
|
284
|
+
functionSignature: z.ZodString;
|
|
285
|
+
problemStatement: z.ZodString;
|
|
286
|
+
inputVariable: z.ZodString;
|
|
287
|
+
inputVariableAnnotation: z.ZodString;
|
|
288
|
+
defaultInputValue: z.ZodString;
|
|
289
|
+
referenceSolution: z.ZodString;
|
|
290
|
+
unitTests: z.ZodString;
|
|
291
|
+
name: z.ZodOptional<z.ZodString>;
|
|
292
|
+
points: z.ZodDefault<z.ZodNumber>;
|
|
293
|
+
maxAttemptsCount: z.ZodDefault<z.ZodNumber>;
|
|
294
|
+
timeoutSeconds: z.ZodDefault<z.ZodNumber>;
|
|
295
|
+
guidance: z.ZodDefault<z.ZodString>;
|
|
296
|
+
lo: z.ZodDefault<z.ZodString>;
|
|
297
|
+
blooms: z.ZodDefault<z.ZodString>;
|
|
298
|
+
}, z.core.$strip>;
|
|
299
|
+
export type ProbeablePayload = z.infer<typeof probeablePayloadSchema>;
|
|
300
|
+
export interface ProbeableCreateResult {
|
|
301
|
+
taskId: string;
|
|
302
|
+
jsonPath: string;
|
|
303
|
+
embedLine: string;
|
|
304
|
+
studentFilePath: string;
|
|
305
|
+
probeScriptPath: string;
|
|
306
|
+
unitTestPath: string;
|
|
307
|
+
probeButtonCommand: string;
|
|
308
|
+
runButtonCommand: string;
|
|
309
|
+
suggestedPageMarkdown: string;
|
|
310
|
+
}
|
|
282
311
|
export declare const createAssessmentInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
283
312
|
type: z.ZodLiteral<"multiple-choice">;
|
|
284
313
|
workspace: z.ZodString;
|
|
@@ -299,12 +328,16 @@ export declare const createAssessmentInputSchema: z.ZodDiscriminatedUnion<[z.Zod
|
|
|
299
328
|
type: z.ZodLiteral<"llm-based-auto-rubric">;
|
|
300
329
|
workspace: z.ZodString;
|
|
301
330
|
payload: z.ZodUnknown;
|
|
331
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
332
|
+
type: z.ZodLiteral<"probeable-question-act">;
|
|
333
|
+
workspace: z.ZodString;
|
|
334
|
+
payload: z.ZodUnknown;
|
|
302
335
|
}, z.core.$strip>], "type">;
|
|
303
|
-
export
|
|
336
|
+
export type CreateAssessmentResult = {
|
|
304
337
|
taskId: string;
|
|
305
338
|
jsonPath: string;
|
|
306
339
|
embedLine: string;
|
|
307
|
-
}
|
|
340
|
+
} | ProbeableCreateResult;
|
|
308
341
|
export declare function createAssessmentHandler(raw: unknown): Promise<CreateAssessmentResult>;
|
|
309
342
|
export {};
|
|
310
343
|
//# sourceMappingURL=create-assessment.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-assessment.d.ts","sourceRoot":"","sources":["../../src/tools/create-assessment.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"create-assessment.d.ts","sourceRoot":"","sources":["../../src/tools/create-assessment.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,7 +18,7 @@ export declare const createPageInputSchema: z.ZodObject<{
|
|
|
18
18
|
"2-panels-tree": "2-panels-tree";
|
|
19
19
|
}>;
|
|
20
20
|
learningObjectives: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
21
|
-
files: z.ZodOptional<z.ZodArray<z.ZodString
|
|
21
|
+
files: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
22
22
|
markdownBody: z.ZodString;
|
|
23
23
|
chapterFolder: z.ZodOptional<z.ZodString>;
|
|
24
24
|
}, z.core.$strip>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-page.d.ts","sourceRoot":"","sources":["../../src/tools/create-page.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CA6BvE;AAED,eAAO,MAAM,UAAU,+EAMb,CAAC;AAEX,eAAO,MAAM,YAAY,uCAAwC,CAAC;AAElE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"create-page.d.ts","sourceRoot":"","sources":["../../src/tools/create-page.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CA6BvE;AAED,eAAO,MAAM,UAAU,+EAMb,CAAC;AAEX,eAAO,MAAM,YAAY,uCAAwC,CAAC;AAElE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;iBAiC/B,CAAC;AAEJ,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,UAAU,CAAC;IACxB,MAAM,EAAE,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;IACtC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,QAAQ,CAgB9D;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,KAAK,EAAE,eAAe,GACrB,gBAAgB,CA6BlB;AAED,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,gBAAgB,CAAC,CAO3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-course.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-course.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,sBAAsB;;;;;iBAQjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAyDD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"fetch-course.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-course.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,sBAAsB;;;;;iBAQjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAyDD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA+GjF"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare const create_page: {
|
|
|
16
16
|
"2-panels-tree": "2-panels-tree";
|
|
17
17
|
}>;
|
|
18
18
|
learningObjectives: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodString>>;
|
|
19
|
-
files: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString
|
|
19
|
+
files: import("zod").ZodPipe<import("zod").ZodTransform<unknown, unknown>, import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>>;
|
|
20
20
|
markdownBody: import("zod").ZodString;
|
|
21
21
|
chapterFolder: import("zod").ZodOptional<import("zod").ZodString>;
|
|
22
22
|
};
|
|
@@ -39,12 +39,15 @@ export declare const create_assessment: {
|
|
|
39
39
|
"multiple-choice": "multiple-choice";
|
|
40
40
|
"code-output-compare": "code-output-compare";
|
|
41
41
|
"fill-in-the-blanks": "fill-in-the-blanks";
|
|
42
|
+
"parsons-puzzle": "parsons-puzzle";
|
|
43
|
+
"llm-based-auto-rubric": "llm-based-auto-rubric";
|
|
44
|
+
"probeable-question-act": "probeable-question-act";
|
|
42
45
|
}>;
|
|
43
46
|
workspace: import("zod").ZodString;
|
|
44
47
|
payload: import("zod").ZodUnknown;
|
|
45
48
|
};
|
|
46
49
|
execute(args: {
|
|
47
|
-
type: "multiple-choice" | "code-output-compare" | "fill-in-the-blanks";
|
|
50
|
+
type: "multiple-choice" | "code-output-compare" | "fill-in-the-blanks" | "parsons-puzzle" | "llm-based-auto-rubric" | "probeable-question-act";
|
|
48
51
|
workspace: string;
|
|
49
52
|
payload: unknown;
|
|
50
53
|
}, context: import("@opencode-ai/plugin").ToolContext): Promise<import("@opencode-ai/plugin").ToolResult>;
|
|
@@ -61,14 +64,14 @@ export declare const validate_guide: {
|
|
|
61
64
|
export declare const fetch_course: {
|
|
62
65
|
description: string;
|
|
63
66
|
args: {
|
|
64
|
-
workspace: import("zod").ZodString
|
|
67
|
+
workspace: import("zod").ZodOptional<import("zod").ZodString>;
|
|
65
68
|
courseId: import("zod").ZodString;
|
|
66
69
|
outputDir: import("zod").ZodOptional<import("zod").ZodString>;
|
|
67
70
|
domain: import("zod").ZodOptional<import("zod").ZodString>;
|
|
68
71
|
};
|
|
69
72
|
execute(args: {
|
|
70
|
-
workspace: string;
|
|
71
73
|
courseId: string;
|
|
74
|
+
workspace?: string | undefined;
|
|
72
75
|
outputDir?: string | undefined;
|
|
73
76
|
domain?: string | undefined;
|
|
74
77
|
}, context: import("@opencode-ai/plugin").ToolContext): Promise<import("@opencode-ai/plugin").ToolResult>;
|
|
@@ -76,7 +79,7 @@ export declare const fetch_course: {
|
|
|
76
79
|
export declare const publish_course: {
|
|
77
80
|
description: string;
|
|
78
81
|
args: {
|
|
79
|
-
workspace: import("zod").ZodString
|
|
82
|
+
workspace: import("zod").ZodOptional<import("zod").ZodString>;
|
|
80
83
|
manifestPath: import("zod").ZodString;
|
|
81
84
|
dryRun: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
82
85
|
force: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
@@ -86,8 +89,8 @@ export declare const publish_course: {
|
|
|
86
89
|
stack: import("zod").ZodOptional<import("zod").ZodString>;
|
|
87
90
|
};
|
|
88
91
|
execute(args: {
|
|
89
|
-
workspace: string;
|
|
90
92
|
manifestPath: string;
|
|
93
|
+
workspace?: string | undefined;
|
|
91
94
|
dryRun?: boolean | undefined;
|
|
92
95
|
force?: boolean | undefined;
|
|
93
96
|
module?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOtB,CAAC;AAOH,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOtB,CAAC;AAOH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;CAkB5B,CAAC;AAIH,eAAO,MAAM,cAAc;;;;;;;;CAOzB,CAAC;AAIH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;CAOvB,CAAC;AAIH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;CAOzB,CAAC;AAQH,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAMzC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish-course.d.ts","sourceRoot":"","sources":["../../src/tools/publish-course.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,wBAAwB;;;;;;;;;iBASnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AA6DD,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,
|
|
1
|
+
{"version":3,"file":"publish-course.d.ts","sourceRoot":"","sources":["../../src/tools/publish-course.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,wBAAwB;;;;;;;;;iBASnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AA6DD,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA4HrF"}
|
package/dist/utils/taskid.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type AssessmentType = 'multiple-choice' | 'code-output-compare' | 'fill-in-the-blanks' | 'parsons-puzzle' | 'llm-based-auto-rubric';
|
|
1
|
+
export type AssessmentType = 'multiple-choice' | 'code-output-compare' | 'fill-in-the-blanks' | 'parsons-puzzle' | 'llm-based-auto-rubric' | 'probeable-question-act';
|
|
2
2
|
export declare const ASSESSMENT_TYPES: AssessmentType[];
|
|
3
3
|
export declare const ANY_TASKID_RE: RegExp;
|
|
4
4
|
export declare function generateTaskId(type: AssessmentType): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"taskid.d.ts","sourceRoot":"","sources":["../../src/utils/taskid.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,qBAAqB,GACrB,oBAAoB,GACpB,gBAAgB,GAChB,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"taskid.d.ts","sourceRoot":"","sources":["../../src/utils/taskid.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,qBAAqB,GACrB,oBAAoB,GACpB,gBAAgB,GAChB,uBAAuB,GACvB,wBAAwB,CAAC;AAE7B,eAAO,MAAM,gBAAgB,EAAE,cAAc,EAO5C,CAAC;AAmBF,eAAO,MAAM,aAAa,QAGzB,CAAC;AAEF,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAK3D;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAOpE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: reference-assessment-types
|
|
3
|
-
description: Payload field reference for multiple-choice, code-output-compare
|
|
3
|
+
description: Payload field reference for multiple-choice, code-output-compare, fill-in-the-blanks, parsons-puzzle, llm-based-auto-rubric, and probeable-question-act assessments. Use when building any assessment payload.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Assessment types
|
|
@@ -307,3 +307,111 @@ Note: auto-rubric uses `panelNumber` (not `panel`) in the opened entries.
|
|
|
307
307
|
- All solutions: `.guides/secure/<filename>` — hidden from students.
|
|
308
308
|
- Never: `.guides/content/<anything>` — student-visible.
|
|
309
309
|
- The tool writes the file only if it does not already exist (safe to re-run).
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## `probeable-question-act` — Probeable Question (Advanced Code Test)
|
|
314
|
+
|
|
315
|
+
A probeable question combines a guide page with custom buttons and an Advanced Code Test assessment. Students first "probe" the reference solution with their own inputs to discover edge cases, then implement the function themselves.
|
|
316
|
+
|
|
317
|
+
### What the tool creates
|
|
318
|
+
|
|
319
|
+
Calling `create_assessment` with `type: 'probeable-question-act'` writes four files and returns an extended result:
|
|
320
|
+
|
|
321
|
+
| File | Location | Visible to students? |
|
|
322
|
+
|---|---|---|
|
|
323
|
+
| Assessment JSON | `.guides/assessments/test-XXXXXXXXXX.json` | No |
|
|
324
|
+
| Student file | `code/functions/probeable_{functionName}.py` | Yes |
|
|
325
|
+
| Probe script | `.guides/probeable_questions/probe_{functionName}.py` | Yes (by design) |
|
|
326
|
+
| Unit test file | `.guides/secure/unit_tests/probeable_questions/{functionName}_test.py` | No |
|
|
327
|
+
|
|
328
|
+
The probe script is intentionally student-visible — students click a button to run it with their probe inputs.
|
|
329
|
+
|
|
330
|
+
### Payload fields
|
|
331
|
+
|
|
332
|
+
```
|
|
333
|
+
functionName string Python function name (snake_case), used as the file stem
|
|
334
|
+
functionSignature string Full def line with type hints, e.g. "def min_index(int_list: list[int]) -> int:"
|
|
335
|
+
problemStatement string Narrative description for the guide page. Must be intentionally vague — omit edge cases and boundary conditions so students must use the probe to discover them.
|
|
336
|
+
inputVariable string Variable students modify to probe, e.g. "int_list"
|
|
337
|
+
inputVariableAnnotation string Python type annotation, e.g. "list[int]"
|
|
338
|
+
defaultInputValue string Default value shown in student file, e.g. "[1, 2, 3]"
|
|
339
|
+
referenceSolution string Complete working function definition (def line + body)
|
|
340
|
+
unitTests string Full Python unittest file content
|
|
341
|
+
name? string Display name (defaults to functionName)
|
|
342
|
+
points? number Default 20
|
|
343
|
+
maxAttemptsCount? number Default 0 (unlimited)
|
|
344
|
+
timeoutSeconds? number Default 40
|
|
345
|
+
guidance? string Default ""
|
|
346
|
+
lo? string Learning objective
|
|
347
|
+
blooms? string Bloom's level
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Assessment JSON fixed fields
|
|
351
|
+
|
|
352
|
+
The tool writes these fields with fixed values — do not override:
|
|
353
|
+
|
|
354
|
+
```
|
|
355
|
+
"instructions": "**Submit your work for evaluation**"
|
|
356
|
+
"command": "python3 .guides/secure/unit_tests/probeable_questions/{functionName}_test.py"
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
The `command` runs the unit test file directly via `python3` (not `pytest`, not `-m unittest`). The overall runner still wraps execution through `python /usr/share/codio/assessments/assessments.py` — the `command` here is the path passed to that runner's `codeEnvConfig`.
|
|
360
|
+
|
|
361
|
+
### Extended return value
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
taskId string e.g. "test-1234567890"
|
|
365
|
+
jsonPath string Absolute path to written assessment JSON
|
|
366
|
+
embedLine string '{Check It!|assessment}(test-XXXXXXXXXX)'
|
|
367
|
+
studentFilePath string 'code/functions/probeable_{functionName}.py'
|
|
368
|
+
probeScriptPath string '.guides/probeable_questions/probe_{functionName}.py'
|
|
369
|
+
unitTestPath string '.guides/secure/unit_tests/probeable_questions/{functionName}_test.py'
|
|
370
|
+
probeButtonCommand string 'python3 .guides/probeable_questions/probe_{functionName}.py'
|
|
371
|
+
runButtonCommand string 'python3 code/functions/probeable_{functionName}.py'
|
|
372
|
+
suggestedPageMarkdown string Complete guide page markdown — pass to @page-author as body_brief
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Orchestrator workflow
|
|
376
|
+
|
|
377
|
+
```
|
|
378
|
+
@assessment-author → payload
|
|
379
|
+
↓
|
|
380
|
+
create_assessment(type: probeable-question-act) → { taskId, embedLine, suggestedPageMarkdown, ... }
|
|
381
|
+
↓
|
|
382
|
+
@page-author (draft mode, body_brief = suggestedPageMarkdown) → markdownBody
|
|
383
|
+
↓
|
|
384
|
+
create_page (layout: 2-panels-tree, files: [studentFilePath]) → page JSON + MD
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Guide page structure
|
|
388
|
+
|
|
389
|
+
The `suggestedPageMarkdown` returned by the tool follows this template — pass it as-is or refine via `@page-author`:
|
|
390
|
+
|
|
391
|
+
```
|
|
392
|
+
{problemStatement}
|
|
393
|
+
|
|
394
|
+
#### Probing the solution to find edge cases
|
|
395
|
+
|
|
396
|
+
Modify {inputVariable} values to check the expected return value and discover edge cases.
|
|
397
|
+
|
|
398
|
+
|||warning
|
|
399
|
+
## `{functionName}` code
|
|
400
|
+
Probing will run the code in the editor. Syntax errors in your file will prevent probing.
|
|
401
|
+
Pro-tip: Leave only `pass` in the `{functionName}` function while probing.
|
|
402
|
+
|||
|
|
403
|
+
|
|
404
|
+
{Probe Solution}(python3 .guides/probeable_questions/probe_{functionName}.py)
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
## Complete the function
|
|
408
|
+
|
|
409
|
+
{Run it !}(python3 code/functions/probeable_{functionName}.py)
|
|
410
|
+
|
|
411
|
+
{Check It!|assessment}(test-XXXXXXXXXX)
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### File naming
|
|
415
|
+
|
|
416
|
+
Files are named by `functionName` (no sequential exercise numbers). If a student or probe file with the same `functionName` already exists, the tool throws a collision error — choose a unique function name per question.
|
|
417
|
+
|