Skip to content

Commit 5c62f90

Browse files
authored
Merge pull request #57 from ForgeOpus/main
Update deployment branch
2 parents 11aeb9a + 37dd46e commit 5c62f90

56 files changed

Lines changed: 3730 additions & 1317 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Claude Code Review
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
claude-review:
8+
# Optional: Filter by PR author
9+
# if: |
10+
# github.event.pull_request.user.login == 'external-contributor' ||
11+
# github.event.pull_request.user.login == 'new-developer' ||
12+
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
13+
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
pull-requests: read
18+
issues: read
19+
id-token: write
20+
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
24+
with:
25+
fetch-depth: 1
26+
27+
- name: Run Claude Code Review
28+
id: claude-review
29+
uses: anthropics/claude-code-action@v1
30+
with:
31+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
32+
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
33+
plugins: 'code-review@claude-code-plugins'
34+
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
35+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
36+
# or https://code.claude.com/docs/en/cli-reference for available options
37+

.github/workflows/claude.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Claude Code
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
pull_request_review_comment:
7+
types: [created]
8+
issues:
9+
types: [opened, assigned]
10+
pull_request_review:
11+
types: [submitted]
12+
13+
jobs:
14+
claude:
15+
if: |
16+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
pull-requests: read
24+
issues: read
25+
id-token: write
26+
actions: read # Required for Claude to read CI results on PRs
27+
steps:
28+
- name: Checkout repository
29+
uses: actions/checkout@v4
30+
with:
31+
fetch-depth: 1
32+
33+
- name: Run Claude Code
34+
id: claude
35+
uses: anthropics/claude-code-action@v1
36+
with:
37+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
38+
39+
# This is an optional setting that allows Claude to read CI results on PRs
40+
additional_permissions: |
41+
actions: read
42+
43+
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
44+
# prompt: 'Update the pull request description to include a summary of changes.'
45+
46+
# Optional: Add claude_args to customize behavior and configuration
47+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
48+
# or https://code.claude.com/docs/en/cli-reference for available options
49+
# claude_args: '--allowed-tools Bash(gh pr:*)'
50+

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@
1313

1414
</div>
1515

16+
<p align="center">
17+
<a href="https://www.producthunt.com/products/forgeopus?embed=true&utm_source=badge-featured&utm_medium=badge&utm_campaign=badge-forgeopus" target="_blank" rel="noopener noreferrer">
18+
<img
19+
alt="ForgeOpus - Where AI masterpieces are forged. Your work, your opus. | Product Hunt"
20+
width="250"
21+
height="54"
22+
src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1080450&theme=light&t=1771311433851"
23+
/>
24+
</a>
25+
</p>
26+
27+
1628
<br />
1729

1830
## ✨ What is VisionForge?

project/block_manager/services/codegen/base.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ def topological_sort(nodes: List[Dict], edges: List[Dict]) -> List[Dict]:
4444
if in_degree[neighbor] == 0:
4545
queue.append(neighbor)
4646

47+
# Cycle detection: if not all nodes were sorted, there's a cycle
48+
if len(sorted_ids) != len(nodes):
49+
# Find nodes that are still in the cycle (have non-zero in-degree)
50+
cycle_nodes = [node_id for node_id, degree in in_degree.items() if degree > 0]
51+
raise ValueError(
52+
f"Graph contains a cycle. Neural networks must be acyclic (feedforward). "
53+
f"Nodes involved in cycle: {', '.join(cycle_nodes[:5])}"
54+
+ (" and more..." if len(cycle_nodes) > 5 else "")
55+
)
56+
4757
# Return nodes in sorted order
4858
return [node_map[node_id] for node_id in sorted_ids if node_id in node_map]
4959

project/block_manager/services/codegen/base_orchestrator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def _generate_code_specs(
129129

130130
processable_nodes = [
131131
n for n in sorted_nodes
132-
if get_node_type(n) not in ('input', 'dataloader', 'output')
132+
if get_node_type(n) not in ('input', 'dataloader', 'output', 'loss', 'metrics', 'groundtruth')
133133
]
134134

135135
for node in processable_nodes:
@@ -193,7 +193,7 @@ def _generate_forward_pass(
193193

194194
processable_nodes = [
195195
n for n in sorted_nodes
196-
if get_node_type(n) not in ('output',)
196+
if get_node_type(n) not in ('output', 'loss', 'metrics', 'groundtruth')
197197
]
198198

199199
for node in processable_nodes:
@@ -273,7 +273,7 @@ def _generate_config_file(self, nodes: List[Dict[str, Any]]) -> str:
273273
input_shape = self._extract_input_shape(nodes)
274274
layer_count = sum(
275275
1 for n in nodes
276-
if get_node_type(n) not in ('input', 'output', 'dataloader')
276+
if get_node_type(n) not in ('input', 'output', 'dataloader', 'loss', 'metrics', 'groundtruth')
277277
)
278278

279279
if layer_count > 20:

project/block_manager/services/codegen/pytorch_group_generator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def _generate_internal_node_specs(
169169
node_type = get_node_type(node)
170170

171171
# Skip special nodes
172-
if node_type in ('input', 'output', 'dataloader'):
172+
if node_type in ('input', 'output', 'dataloader', 'loss'):
173173
continue
174174

175175
node_id = node['id']
@@ -273,8 +273,8 @@ def _generate_forward_pass(
273273
var_map[node_id] = var_name
274274
continue
275275

276-
# Skip output and dataloader nodes (they don't produce code)
277-
if node_type in ('output', 'dataloader'):
276+
# Skip output, dataloader, and loss nodes (they don't produce code)
277+
if node_type in ('output', 'dataloader', 'loss'):
278278
continue
279279

280280
# Get the spec for this node

0 commit comments

Comments
 (0)