crewforge 0.1.0__tar.gz → 0.2.0__tar.gz
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.
- {crewforge-0.1.0/src/crewforge.egg-info → crewforge-0.2.0}/PKG-INFO +83 -7
- {crewforge-0.1.0 → crewforge-0.2.0}/README.md +80 -4
- {crewforge-0.1.0 → crewforge-0.2.0}/pyproject.toml +4 -4
- crewforge-0.2.0/src/crewforge/__init__.py +3 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/cli.py +11 -3
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/core/config.py +1 -0
- crewforge-0.2.0/src/crewforge/recipes/__init__.py +1 -0
- crewforge-0.2.0/src/crewforge/recipes/academic/__init__.py +46 -0
- crewforge-0.2.0/src/crewforge/recipes/academic/agents.py +375 -0
- crewforge-0.2.0/src/crewforge/recipes/academic/citations.py +286 -0
- crewforge-0.2.0/src/crewforge/recipes/academic/cli.py +351 -0
- crewforge-0.2.0/src/crewforge/recipes/academic/disclosure.py +184 -0
- crewforge-0.2.0/src/crewforge/recipes/academic/language.py +85 -0
- crewforge-0.2.0/src/crewforge/recipes/academic/locales/en.yaml +122 -0
- crewforge-0.2.0/src/crewforge/recipes/academic/locales/ms.yaml +174 -0
- crewforge-0.2.0/src/crewforge/recipes/academic/pipeline.py +359 -0
- crewforge-0.2.0/src/crewforge/recipes/academic/report.py +247 -0
- crewforge-0.2.0/src/crewforge/recipes/academic/settings.py +46 -0
- {crewforge-0.1.0 → crewforge-0.2.0/src/crewforge.egg-info}/PKG-INFO +83 -7
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge.egg-info/SOURCES.txt +11 -0
- crewforge-0.1.0/src/crewforge/__init__.py +0 -3
- crewforge-0.1.0/src/crewforge/recipes/__init__.py +0 -1
- {crewforge-0.1.0 → crewforge-0.2.0}/LICENSE +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/setup.cfg +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/__main__.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/cli_support.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/core/__init__.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/core/agent.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/core/client.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/core/crew.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/core/errors.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/core/parsing.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/core/providers.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/core/usage.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/py.typed +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/__init__.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/agents.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/analytics.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/appcheck.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/cli.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/formatters.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/generator.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/pipeline.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/scaffold.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/templates/docker-compose.j2 +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/templates/dockerfile.j2 +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/templates/env.example.j2 +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/templates/fastapi_main.j2 +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/templates/model.j2 +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/templates/requirements.j2 +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/templates/route.j2 +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/templates/test.j2 +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/api/utils.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/content/__init__.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/content/agents.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/content/cli.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/content/export.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/content/pipeline.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/content/settings.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/content/text.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/docs/__init__.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/docs/agents.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/docs/cli.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/docs/export.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/docs/index.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/docs/ingest.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/docs/pipeline.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/docs/retrieve.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/docs/settings.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/review/__init__.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/review/agents.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/review/cli.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/review/pipeline.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/review/report.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge/recipes/review/sources.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge.egg-info/dependency_links.txt +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge.egg-info/entry_points.txt +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge.egg-info/requires.txt +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/src/crewforge.egg-info/top_level.txt +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/tests/test_honest_failure_e2e.py +0 -0
- {crewforge-0.1.0 → crewforge-0.2.0}/tests/test_readme.py +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crewforge
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: One crew of LLM agents,
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: One crew of LLM agents, five recipes: code review, document Q&A, API scaffolding, content and honest academic-writing help — on any OpenAI-compatible provider.
|
|
5
5
|
Author: Muhammad Aiman
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/aimanmalib/crewforge
|
|
8
8
|
Project-URL: Repository, https://github.com/aimanmalib/crewforge
|
|
9
9
|
Project-URL: Issues, https://github.com/aimanmalib/crewforge/issues
|
|
10
10
|
Project-URL: Changelog, https://github.com/aimanmalib/crewforge/blob/main/CHANGELOG.md
|
|
11
|
-
Keywords: llm,agents,multi-agent,openai,code-review,rag,fastapi,content-generation,cli
|
|
11
|
+
Keywords: llm,agents,multi-agent,openai,code-review,rag,fastapi,content-generation,academic-writing,cli
|
|
12
12
|
Classifier: Development Status :: 3 - Alpha
|
|
13
13
|
Classifier: Environment :: Console
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
@@ -47,9 +47,10 @@ Dynamic: license-file
|
|
|
47
47
|
|
|
48
48
|
# crewforge
|
|
49
49
|
|
|
50
|
-
**One crew of LLM agents,
|
|
50
|
+
**One crew of LLM agents, five recipes — code review, document Q&A, API scaffolding, content and honest academic-writing help — on any OpenAI-compatible provider, and it fails loudly instead of pretending.**
|
|
51
51
|
|
|
52
52
|
[](https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml)
|
|
53
|
+
[](https://pypi.org/project/crewforge/)
|
|
53
54
|

|
|
54
55
|

|
|
55
56
|
|
|
@@ -58,6 +59,7 @@ crewforge review src/ # six reviewers + a summa
|
|
|
58
59
|
crewforge ask handbook.pdf -q "How many leave days?" --verify
|
|
59
60
|
crewforge scaffold "Todo API: list, create and delete todos" -o todo-api
|
|
60
61
|
crewforge write "Why unit tests matter" -f markdown -f html
|
|
62
|
+
crewforge academic feedback draft.md --brief brief.md --language ms
|
|
61
63
|
```
|
|
62
64
|
|
|
63
65
|
<p align="center">
|
|
@@ -65,7 +67,7 @@ crewforge write "Why unit tests matter" -f markdown -f html
|
|
|
65
67
|
</p>
|
|
66
68
|
<p align="center"><sub>A real run of <code>crewforge review</code>: seven agents, ~25 s, provider-reported tokens. Recorded with <a href="https://github.com/charmbracelet/vhs">VHS</a> from <a href="https://github.com/aimanmalib/crewforge/blob/main/docs/demo/review.tape"><code>docs/demo/review.tape</code></a> using Gemini 3.8 Flash through an OpenAI-compatible gateway (the <code>custom</code> provider). The wait for the model is shown in full.</sub></p>
|
|
67
69
|
|
|
68
|
-
## Why one crew,
|
|
70
|
+
## Why one crew, many recipes
|
|
69
71
|
|
|
70
72
|
crewforge started as four separate command-line tools —
|
|
71
73
|
[codeguard](https://github.com/aimanmalib/codeguard),
|
|
@@ -87,6 +89,10 @@ apply to every recipe: non-streaming requests, bounded retries, usage numbers
|
|
|
87
89
|
taken only from the provider, keys only from the environment, and no run that
|
|
88
90
|
reports success when an agent produced nothing.
|
|
89
91
|
|
|
92
|
+
A fifth recipe, `academic`, replaces a standalone "academic writing pipeline"
|
|
93
|
+
that drafted essays and marketed itself as AI-detector-resistant. Only the
|
|
94
|
+
honest parts were kept; see [docs/porting.md](https://github.com/aimanmalib/crewforge/blob/main/docs/porting.md#academic-from-hermes-mimo-writer).
|
|
95
|
+
|
|
90
96
|
## 60-second quickstart
|
|
91
97
|
|
|
92
98
|
```bash
|
|
@@ -128,6 +134,10 @@ tables are trimmed to their totals.
|
|
|
128
134
|
| `scaffold "DESCRIPTION"` | parser → schema → router, model, auth, test_gen, doc_gen (parallel) → validator | A runnable FastAPI project with `openapi.json`, tests and docs |
|
|
129
135
|
| `validate PATH` | validator (no LLM) | Spec check; for a project directory, also checks the app serves every spec operation |
|
|
130
136
|
| `write "TOPIC"` | research → outline → writer → SEO → editor ⇄ quality → translator → publisher | Article as Markdown/HTML/JSON, social snippets, a usage file |
|
|
137
|
+
| `academic plan BRIEF` | brief → planner | Research questions, an outline with a word budget that adds up, sources to find, suggested readings labelled UNVERIFIED |
|
|
138
|
+
| `academic feedback DRAFT` | structure, argument, clarity, citations (parallel) + a citation cross-check (no LLM) | Comments tied to quoted text in your draft; no rewriting |
|
|
139
|
+
| `academic cite REFS` | formatter | Your references in APA 7, IEEE or Harvard; nothing added, missing details listed |
|
|
140
|
+
| `academic disclose` | none (no LLM) | An AI-use statement built from the record of what the tool did |
|
|
131
141
|
|
|
132
142
|
### `review`
|
|
133
143
|
|
|
@@ -212,6 +222,68 @@ length (`--words` is a target given to the agents, not a hard limit), and the
|
|
|
212
222
|
research agent has no web access, so statistics it quotes come from the model's
|
|
213
223
|
training data. Review articles before publishing them.
|
|
214
224
|
|
|
225
|
+
### `academic`
|
|
226
|
+
|
|
227
|
+
An honest assistant for a student's or researcher's **own** work. It plans,
|
|
228
|
+
comments and formats; it does not write the assignment, does not invent
|
|
229
|
+
references, and has no "humanise" or AI-detector-evasion feature. Output in
|
|
230
|
+
English or Malaysian Malay (`--language en|ms`; Malay output is checked for
|
|
231
|
+
Indonesian forms such as *karena* or *kualitas*). Every step is recorded
|
|
232
|
+
(file names and hashes, never content or keys) so `disclose` can write the
|
|
233
|
+
AI-use statement many universities now ask for.
|
|
234
|
+
|
|
235
|
+
```text
|
|
236
|
+
$ crewforge academic plan brief.md -f markdown # a 1,200-word TSL3013 essay brief
|
|
237
|
+
# Assignment plan: Regulated Integration over Prohibition: ...
|
|
238
|
+
- **Target length:** 1,200 words
|
|
239
|
+
- **Citation style:** APA 7th edition
|
|
240
|
+
## Research questions
|
|
241
|
+
1. What pedagogical benefits does generative AI offer secondary school students completing homework tasks?
|
|
242
|
+
...
|
|
243
|
+
| # | Section | Words | Purpose |
|
|
244
|
+
| 1 | Introduction | 150 | ... | ... Total: 1,200 words
|
|
245
|
+
## Suggested readings (UNVERIFIED)
|
|
246
|
+
> The AI proposed these. They may not exist, or may not say what is claimed. ...
|
|
247
|
+
- ⚠ **UNVERIFIED: proposed or altered by the AI, check it** — Holmes, W., & Tuomi, I. (2022). ...
|
|
248
|
+
total 2 calls 9,034 tokens (provider-reported)
|
|
249
|
+
|
|
250
|
+
$ crewforge academic feedback draft.md --brief brief.md -f markdown
|
|
251
|
+
## Argument
|
|
252
|
+
- **Paragraph 2** (major): “Everyone knows that tuition in Malaysia is very expensive.”
|
|
253
|
+
- This is an unsupported generalization and an informal assertion rather than an evidence-based academic claim.
|
|
254
|
+
- *Suggestion:* Replace the appeal to common knowledge with scholarly evidence or empirical data ...
|
|
255
|
+
## Citation check (no AI)
|
|
256
|
+
**Cited in the text but not in the reference list:**
|
|
257
|
+
- Lim, 2024
|
|
258
|
+
total 4 calls 17,892 tokens (provider-reported)
|
|
259
|
+
|
|
260
|
+
$ crewforge academic cite refs.txt --style ieee --language ms -f markdown
|
|
261
|
+
[4] W. Holmes, M. Bialik, and C. Fadel, *Artificial Intelligence in Education: ...*. Center for Curriculum Redesign, 2019, ISBN: 978-1-7941-1293-0.
|
|
262
|
+
- ⚠ nombor semak ISBN salah: 9781794112930
|
|
263
|
+
- Butiran yang perlu ditambah: tempat penerbitan
|
|
264
|
+
|
|
265
|
+
$ crewforge academic disclose --language ms # no LLM, no key
|
|
266
|
+
## Pernyataan Penggunaan AI
|
|
267
|
+
Saya menggunakan crewforge academic (versi 0.1.0), sebuah alat berbantukan AI, dengan model gemini-3.8-flash (melalui gateway serasi OpenAI), bagi bahagian tugasan berikut:
|
|
268
|
+
- 22 Oktober 2026: Perancangan: alat ini menukar taklimat tugasan (brief-ms.md) kepada 3 soalan kajian, rangka 5 bahagian dan peruntukan perkataan. ...
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
How sources are labelled — there is no "verified" status, because the tool
|
|
272
|
+
cannot check that a source exists:
|
|
273
|
+
|
|
274
|
+
| Source | Label |
|
|
275
|
+
|---|---|
|
|
276
|
+
| You supplied it | *supplied by you (not checked online)* |
|
|
277
|
+
| The model proposed it, with a DOI, URL or valid ISBN | **UNVERIFIED** — check it |
|
|
278
|
+
| The model proposed it with none of those | **LIKELY FABRICATED** |
|
|
279
|
+
| The model added a DOI/URL/ISBN to a reference you supplied | **UNVERIFIED**, naming the added identifier |
|
|
280
|
+
|
|
281
|
+
A DOI the model proposes can be made up too, which is why even those stay
|
|
282
|
+
unverified. All text the student sees lives in
|
|
283
|
+
`src/crewforge/recipes/academic/locales/{en,ms}.yaml`; defaults (language,
|
|
284
|
+
style, log file, input size, suggestion length) are the `academic:` section of
|
|
285
|
+
`crewforge.yaml`.
|
|
286
|
+
|
|
215
287
|
## Providers
|
|
216
288
|
|
|
217
289
|
The table is checked against the code by `tests/test_readme.py`.
|
|
@@ -239,13 +311,14 @@ An unknown provider name is a configuration error, not a silent fallback.
|
|
|
239
311
|
|
|
240
312
|
```mermaid
|
|
241
313
|
flowchart LR
|
|
242
|
-
CLI["crewforge CLI<br/>review · ask · summarize · ingest<br/>scaffold · validate · write"] --> R
|
|
314
|
+
CLI["crewforge CLI<br/>review · ask · summarize · ingest<br/>scaffold · validate · write<br/>academic plan · feedback · cite · disclose"] --> R
|
|
243
315
|
|
|
244
316
|
subgraph R["Recipes (src/crewforge/recipes)"]
|
|
245
317
|
RV[review]
|
|
246
318
|
DC[docs]
|
|
247
319
|
AP[api]
|
|
248
320
|
CT[content]
|
|
321
|
+
AC[academic]
|
|
249
322
|
end
|
|
250
323
|
|
|
251
324
|
R --> CREW
|
|
@@ -317,7 +390,7 @@ Validation: INVALID · 0/100 (0 operation(s) checked, 1 error(s), 0 warning(s))
|
|
|
317
390
|
ERROR: No endpoints defined (paths is empty)
|
|
318
391
|
```
|
|
319
392
|
|
|
320
|
-
| Situation | Before (the
|
|
393
|
+
| Situation | Before (the earlier tools) | crewforge |
|
|
321
394
|
|---|---|---|
|
|
322
395
|
| Every reviewer returns nothing | "Review Complete!", exit 0 | exit 1, names each reviewer |
|
|
323
396
|
| A reviewer answers in prose | treated as a review | exit 1, `agent 'style' (parse)` |
|
|
@@ -327,6 +400,9 @@ Validation: INVALID · 0/100 (0 operation(s) checked, 1 error(s), 0 warning(s))
|
|
|
327
400
|
| Quality never reaches the threshold | article published | exit 1 unless `--accept-below-threshold` |
|
|
328
401
|
| Question matches no passage | model asked to answer from nothing | exit 1, names `retriever`, no LLM call |
|
|
329
402
|
| Generated code does not compile | template silently reused | exit 1, names the agent |
|
|
403
|
+
| Model proposes a reference with no DOI/URL/ISBN | hermes-mimo-writer put invented "plausible" references in the bibliography | labelled LIKELY FABRICATED, never verified |
|
|
404
|
+
| Formatter skips a reference you supplied | n/a | exit 1, names `formatter` |
|
|
405
|
+
| `disclose` finds no recorded AI use | n/a | exit 1, no statement written |
|
|
330
406
|
|
|
331
407
|
Exit codes: `0` success · `1` run failed (agent, validator or provider) · `2`
|
|
332
408
|
usage or configuration error (bad flag, unknown provider, missing key).
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# crewforge
|
|
2
2
|
|
|
3
|
-
**One crew of LLM agents,
|
|
3
|
+
**One crew of LLM agents, five recipes — code review, document Q&A, API scaffolding, content and honest academic-writing help — on any OpenAI-compatible provider, and it fails loudly instead of pretending.**
|
|
4
4
|
|
|
5
5
|
[](https://github.com/aimanmalib/crewforge/actions/workflows/ci.yml)
|
|
6
|
+
[](https://pypi.org/project/crewforge/)
|
|
6
7
|

|
|
7
8
|

|
|
8
9
|
|
|
@@ -11,6 +12,7 @@ crewforge review src/ # six reviewers + a summa
|
|
|
11
12
|
crewforge ask handbook.pdf -q "How many leave days?" --verify
|
|
12
13
|
crewforge scaffold "Todo API: list, create and delete todos" -o todo-api
|
|
13
14
|
crewforge write "Why unit tests matter" -f markdown -f html
|
|
15
|
+
crewforge academic feedback draft.md --brief brief.md --language ms
|
|
14
16
|
```
|
|
15
17
|
|
|
16
18
|
<p align="center">
|
|
@@ -18,7 +20,7 @@ crewforge write "Why unit tests matter" -f markdown -f html
|
|
|
18
20
|
</p>
|
|
19
21
|
<p align="center"><sub>A real run of <code>crewforge review</code>: seven agents, ~25 s, provider-reported tokens. Recorded with <a href="https://github.com/charmbracelet/vhs">VHS</a> from <a href="https://github.com/aimanmalib/crewforge/blob/main/docs/demo/review.tape"><code>docs/demo/review.tape</code></a> using Gemini 3.8 Flash through an OpenAI-compatible gateway (the <code>custom</code> provider). The wait for the model is shown in full.</sub></p>
|
|
20
22
|
|
|
21
|
-
## Why one crew,
|
|
23
|
+
## Why one crew, many recipes
|
|
22
24
|
|
|
23
25
|
crewforge started as four separate command-line tools —
|
|
24
26
|
[codeguard](https://github.com/aimanmalib/codeguard),
|
|
@@ -40,6 +42,10 @@ apply to every recipe: non-streaming requests, bounded retries, usage numbers
|
|
|
40
42
|
taken only from the provider, keys only from the environment, and no run that
|
|
41
43
|
reports success when an agent produced nothing.
|
|
42
44
|
|
|
45
|
+
A fifth recipe, `academic`, replaces a standalone "academic writing pipeline"
|
|
46
|
+
that drafted essays and marketed itself as AI-detector-resistant. Only the
|
|
47
|
+
honest parts were kept; see [docs/porting.md](https://github.com/aimanmalib/crewforge/blob/main/docs/porting.md#academic-from-hermes-mimo-writer).
|
|
48
|
+
|
|
43
49
|
## 60-second quickstart
|
|
44
50
|
|
|
45
51
|
```bash
|
|
@@ -81,6 +87,10 @@ tables are trimmed to their totals.
|
|
|
81
87
|
| `scaffold "DESCRIPTION"` | parser → schema → router, model, auth, test_gen, doc_gen (parallel) → validator | A runnable FastAPI project with `openapi.json`, tests and docs |
|
|
82
88
|
| `validate PATH` | validator (no LLM) | Spec check; for a project directory, also checks the app serves every spec operation |
|
|
83
89
|
| `write "TOPIC"` | research → outline → writer → SEO → editor ⇄ quality → translator → publisher | Article as Markdown/HTML/JSON, social snippets, a usage file |
|
|
90
|
+
| `academic plan BRIEF` | brief → planner | Research questions, an outline with a word budget that adds up, sources to find, suggested readings labelled UNVERIFIED |
|
|
91
|
+
| `academic feedback DRAFT` | structure, argument, clarity, citations (parallel) + a citation cross-check (no LLM) | Comments tied to quoted text in your draft; no rewriting |
|
|
92
|
+
| `academic cite REFS` | formatter | Your references in APA 7, IEEE or Harvard; nothing added, missing details listed |
|
|
93
|
+
| `academic disclose` | none (no LLM) | An AI-use statement built from the record of what the tool did |
|
|
84
94
|
|
|
85
95
|
### `review`
|
|
86
96
|
|
|
@@ -165,6 +175,68 @@ length (`--words` is a target given to the agents, not a hard limit), and the
|
|
|
165
175
|
research agent has no web access, so statistics it quotes come from the model's
|
|
166
176
|
training data. Review articles before publishing them.
|
|
167
177
|
|
|
178
|
+
### `academic`
|
|
179
|
+
|
|
180
|
+
An honest assistant for a student's or researcher's **own** work. It plans,
|
|
181
|
+
comments and formats; it does not write the assignment, does not invent
|
|
182
|
+
references, and has no "humanise" or AI-detector-evasion feature. Output in
|
|
183
|
+
English or Malaysian Malay (`--language en|ms`; Malay output is checked for
|
|
184
|
+
Indonesian forms such as *karena* or *kualitas*). Every step is recorded
|
|
185
|
+
(file names and hashes, never content or keys) so `disclose` can write the
|
|
186
|
+
AI-use statement many universities now ask for.
|
|
187
|
+
|
|
188
|
+
```text
|
|
189
|
+
$ crewforge academic plan brief.md -f markdown # a 1,200-word TSL3013 essay brief
|
|
190
|
+
# Assignment plan: Regulated Integration over Prohibition: ...
|
|
191
|
+
- **Target length:** 1,200 words
|
|
192
|
+
- **Citation style:** APA 7th edition
|
|
193
|
+
## Research questions
|
|
194
|
+
1. What pedagogical benefits does generative AI offer secondary school students completing homework tasks?
|
|
195
|
+
...
|
|
196
|
+
| # | Section | Words | Purpose |
|
|
197
|
+
| 1 | Introduction | 150 | ... | ... Total: 1,200 words
|
|
198
|
+
## Suggested readings (UNVERIFIED)
|
|
199
|
+
> The AI proposed these. They may not exist, or may not say what is claimed. ...
|
|
200
|
+
- ⚠ **UNVERIFIED: proposed or altered by the AI, check it** — Holmes, W., & Tuomi, I. (2022). ...
|
|
201
|
+
total 2 calls 9,034 tokens (provider-reported)
|
|
202
|
+
|
|
203
|
+
$ crewforge academic feedback draft.md --brief brief.md -f markdown
|
|
204
|
+
## Argument
|
|
205
|
+
- **Paragraph 2** (major): “Everyone knows that tuition in Malaysia is very expensive.”
|
|
206
|
+
- This is an unsupported generalization and an informal assertion rather than an evidence-based academic claim.
|
|
207
|
+
- *Suggestion:* Replace the appeal to common knowledge with scholarly evidence or empirical data ...
|
|
208
|
+
## Citation check (no AI)
|
|
209
|
+
**Cited in the text but not in the reference list:**
|
|
210
|
+
- Lim, 2024
|
|
211
|
+
total 4 calls 17,892 tokens (provider-reported)
|
|
212
|
+
|
|
213
|
+
$ crewforge academic cite refs.txt --style ieee --language ms -f markdown
|
|
214
|
+
[4] W. Holmes, M. Bialik, and C. Fadel, *Artificial Intelligence in Education: ...*. Center for Curriculum Redesign, 2019, ISBN: 978-1-7941-1293-0.
|
|
215
|
+
- ⚠ nombor semak ISBN salah: 9781794112930
|
|
216
|
+
- Butiran yang perlu ditambah: tempat penerbitan
|
|
217
|
+
|
|
218
|
+
$ crewforge academic disclose --language ms # no LLM, no key
|
|
219
|
+
## Pernyataan Penggunaan AI
|
|
220
|
+
Saya menggunakan crewforge academic (versi 0.1.0), sebuah alat berbantukan AI, dengan model gemini-3.8-flash (melalui gateway serasi OpenAI), bagi bahagian tugasan berikut:
|
|
221
|
+
- 22 Oktober 2026: Perancangan: alat ini menukar taklimat tugasan (brief-ms.md) kepada 3 soalan kajian, rangka 5 bahagian dan peruntukan perkataan. ...
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
How sources are labelled — there is no "verified" status, because the tool
|
|
225
|
+
cannot check that a source exists:
|
|
226
|
+
|
|
227
|
+
| Source | Label |
|
|
228
|
+
|---|---|
|
|
229
|
+
| You supplied it | *supplied by you (not checked online)* |
|
|
230
|
+
| The model proposed it, with a DOI, URL or valid ISBN | **UNVERIFIED** — check it |
|
|
231
|
+
| The model proposed it with none of those | **LIKELY FABRICATED** |
|
|
232
|
+
| The model added a DOI/URL/ISBN to a reference you supplied | **UNVERIFIED**, naming the added identifier |
|
|
233
|
+
|
|
234
|
+
A DOI the model proposes can be made up too, which is why even those stay
|
|
235
|
+
unverified. All text the student sees lives in
|
|
236
|
+
`src/crewforge/recipes/academic/locales/{en,ms}.yaml`; defaults (language,
|
|
237
|
+
style, log file, input size, suggestion length) are the `academic:` section of
|
|
238
|
+
`crewforge.yaml`.
|
|
239
|
+
|
|
168
240
|
## Providers
|
|
169
241
|
|
|
170
242
|
The table is checked against the code by `tests/test_readme.py`.
|
|
@@ -192,13 +264,14 @@ An unknown provider name is a configuration error, not a silent fallback.
|
|
|
192
264
|
|
|
193
265
|
```mermaid
|
|
194
266
|
flowchart LR
|
|
195
|
-
CLI["crewforge CLI<br/>review · ask · summarize · ingest<br/>scaffold · validate · write"] --> R
|
|
267
|
+
CLI["crewforge CLI<br/>review · ask · summarize · ingest<br/>scaffold · validate · write<br/>academic plan · feedback · cite · disclose"] --> R
|
|
196
268
|
|
|
197
269
|
subgraph R["Recipes (src/crewforge/recipes)"]
|
|
198
270
|
RV[review]
|
|
199
271
|
DC[docs]
|
|
200
272
|
AP[api]
|
|
201
273
|
CT[content]
|
|
274
|
+
AC[academic]
|
|
202
275
|
end
|
|
203
276
|
|
|
204
277
|
R --> CREW
|
|
@@ -270,7 +343,7 @@ Validation: INVALID · 0/100 (0 operation(s) checked, 1 error(s), 0 warning(s))
|
|
|
270
343
|
ERROR: No endpoints defined (paths is empty)
|
|
271
344
|
```
|
|
272
345
|
|
|
273
|
-
| Situation | Before (the
|
|
346
|
+
| Situation | Before (the earlier tools) | crewforge |
|
|
274
347
|
|---|---|---|
|
|
275
348
|
| Every reviewer returns nothing | "Review Complete!", exit 0 | exit 1, names each reviewer |
|
|
276
349
|
| A reviewer answers in prose | treated as a review | exit 1, `agent 'style' (parse)` |
|
|
@@ -280,6 +353,9 @@ Validation: INVALID · 0/100 (0 operation(s) checked, 1 error(s), 0 warning(s))
|
|
|
280
353
|
| Quality never reaches the threshold | article published | exit 1 unless `--accept-below-threshold` |
|
|
281
354
|
| Question matches no passage | model asked to answer from nothing | exit 1, names `retriever`, no LLM call |
|
|
282
355
|
| Generated code does not compile | template silently reused | exit 1, names the agent |
|
|
356
|
+
| Model proposes a reference with no DOI/URL/ISBN | hermes-mimo-writer put invented "plausible" references in the bibliography | labelled LIKELY FABRICATED, never verified |
|
|
357
|
+
| Formatter skips a reference you supplied | n/a | exit 1, names `formatter` |
|
|
358
|
+
| `disclose` finds no recorded AI use | n/a | exit 1, no statement written |
|
|
283
359
|
|
|
284
360
|
Exit codes: `0` success · `1` run failed (agent, validator or provider) · `2`
|
|
285
361
|
usage or configuration error (bad flag, unknown provider, missing key).
|
|
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "crewforge"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "One crew of LLM agents,
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "One crew of LLM agents, five recipes: code review, document Q&A, API scaffolding, content and honest academic-writing help — on any OpenAI-compatible provider."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
11
11
|
license-files = ["LICENSE"]
|
|
12
12
|
requires-python = ">=3.10"
|
|
13
13
|
authors = [{ name = "Muhammad Aiman" }]
|
|
14
|
-
keywords = ["llm", "agents", "multi-agent", "openai", "code-review", "rag", "fastapi", "content-generation", "cli"]
|
|
14
|
+
keywords = ["llm", "agents", "multi-agent", "openai", "code-review", "rag", "fastapi", "content-generation", "academic-writing", "cli"]
|
|
15
15
|
classifiers = [
|
|
16
16
|
"Development Status :: 3 - Alpha",
|
|
17
17
|
"Environment :: Console",
|
|
@@ -61,7 +61,7 @@ crewforge = "crewforge.cli:main"
|
|
|
61
61
|
where = ["src"]
|
|
62
62
|
|
|
63
63
|
[tool.setuptools.package-data]
|
|
64
|
-
crewforge = ["py.typed", "recipes/api/templates/*.j2"]
|
|
64
|
+
crewforge = ["py.typed", "recipes/api/templates/*.j2", "recipes/academic/locales/*.yaml"]
|
|
65
65
|
|
|
66
66
|
[tool.pytest.ini_options]
|
|
67
67
|
testpaths = ["tests"]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""``crewforge`` command line: global provider options + the
|
|
1
|
+
"""``crewforge`` command line: global provider options + the recipes."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -13,6 +13,7 @@ from .cli_support import EXIT_USAGE, console, err_console, fail
|
|
|
13
13
|
from .core.config import LLMConfig, Settings
|
|
14
14
|
from .core.errors import ConfigError
|
|
15
15
|
from .core.providers import ENV_API_KEY, PROVIDERS
|
|
16
|
+
from .recipes.academic.cli import commands as academic_commands
|
|
16
17
|
from .recipes.api.cli import commands as api_commands
|
|
17
18
|
from .recipes.content.cli import commands as content_commands
|
|
18
19
|
from .recipes.docs.cli import commands as docs_commands
|
|
@@ -41,7 +42,7 @@ from .recipes.review.cli import commands as review_commands
|
|
|
41
42
|
@click.option("--verbose", "-v", is_flag=True, help="Log HTTP retries and agent progress.")
|
|
42
43
|
@click.pass_context
|
|
43
44
|
def main(ctx, provider, model, base_url, config_path, verbose):
|
|
44
|
-
"""One crew of LLM agents,
|
|
45
|
+
"""One crew of LLM agents, five recipes, any OpenAI-compatible provider.
|
|
45
46
|
|
|
46
47
|
\b
|
|
47
48
|
Recipes:
|
|
@@ -52,6 +53,7 @@ def main(ctx, provider, model, base_url, config_path, verbose):
|
|
|
52
53
|
scaffold natural language -> FastAPI project + OpenAPI spec
|
|
53
54
|
validate check an OpenAPI spec (and a scaffolded app) offline
|
|
54
55
|
write research -> outline -> write -> SEO -> edit -> quality -> publish
|
|
56
|
+
academic plan / feedback / cite / disclose for your own assignment
|
|
55
57
|
|
|
56
58
|
API keys are read from the environment only (e.g. OPENAI_API_KEY) and are
|
|
57
59
|
never written to disk. Exit codes: 0 ok, 1 run failed, 2 usage/config error.
|
|
@@ -120,7 +122,13 @@ def init(ctx, output, force):
|
|
|
120
122
|
)
|
|
121
123
|
|
|
122
124
|
|
|
123
|
-
for _cmd in (
|
|
125
|
+
for _cmd in (
|
|
126
|
+
*review_commands,
|
|
127
|
+
*docs_commands,
|
|
128
|
+
*api_commands,
|
|
129
|
+
*content_commands,
|
|
130
|
+
*academic_commands,
|
|
131
|
+
):
|
|
124
132
|
main.add_command(_cmd)
|
|
125
133
|
|
|
126
134
|
|
|
@@ -155,6 +155,7 @@ class Settings(BaseModel):
|
|
|
155
155
|
docs: dict[str, Any] = Field(default_factory=dict)
|
|
156
156
|
api: dict[str, Any] = Field(default_factory=dict)
|
|
157
157
|
content: dict[str, Any] = Field(default_factory=dict)
|
|
158
|
+
academic: dict[str, Any] = Field(default_factory=dict)
|
|
158
159
|
|
|
159
160
|
@classmethod
|
|
160
161
|
def from_yaml(cls, path: str | Path) -> Settings:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""The recipes: review (code), docs (Q&A), api (scaffolding), content (articles), academic."""
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""``academic`` recipe: an honest academic writing assistant.
|
|
2
|
+
|
|
3
|
+
It helps a student or researcher plan and improve their OWN work: parse a
|
|
4
|
+
brief into a plan, comment on a draft, format references the user supplies,
|
|
5
|
+
and write an AI-use disclosure from a record of what the tool actually did.
|
|
6
|
+
It does not write assignments, does not invent references, and has no
|
|
7
|
+
"humanise" or detector-evasion feature (see docs/porting.md).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from .agents import (
|
|
11
|
+
ArgumentAgent,
|
|
12
|
+
BriefAgent,
|
|
13
|
+
CitationReviewAgent,
|
|
14
|
+
ClarityAgent,
|
|
15
|
+
FormatterAgent,
|
|
16
|
+
PlannerAgent,
|
|
17
|
+
StructureAgent,
|
|
18
|
+
)
|
|
19
|
+
from .citations import SourceCheck, analyse_draft, check_formatted, check_source, identifiers
|
|
20
|
+
from .disclosure import build_statement, make_record, read_records
|
|
21
|
+
from .pipeline import AcademicCrew, CiteResult, FeedbackResult, PlanResult, allocate_words
|
|
22
|
+
from .settings import AcademicSettings
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
"AcademicCrew",
|
|
26
|
+
"AcademicSettings",
|
|
27
|
+
"ArgumentAgent",
|
|
28
|
+
"BriefAgent",
|
|
29
|
+
"CitationReviewAgent",
|
|
30
|
+
"CiteResult",
|
|
31
|
+
"ClarityAgent",
|
|
32
|
+
"FeedbackResult",
|
|
33
|
+
"FormatterAgent",
|
|
34
|
+
"PlanResult",
|
|
35
|
+
"PlannerAgent",
|
|
36
|
+
"SourceCheck",
|
|
37
|
+
"StructureAgent",
|
|
38
|
+
"allocate_words",
|
|
39
|
+
"analyse_draft",
|
|
40
|
+
"build_statement",
|
|
41
|
+
"check_formatted",
|
|
42
|
+
"check_source",
|
|
43
|
+
"identifiers",
|
|
44
|
+
"make_record",
|
|
45
|
+
"read_records",
|
|
46
|
+
]
|