Skip to content

feat(ascend,hygon): register AI-core/dcucores and support new and legacy vnpus config - #18

Merged
hami-robot[bot] merged 8 commits into
Project-HAMi:masterfrom
Wangmin362:feat/support-new-npu-template
Jul 7, 2026
Merged

hami-robot[bot] merged 8 commits into
Project-HAMi:masterfrom
Wangmin362:feat/support-new-npu-template

Conversation

@Wangmin362

@Wangmin362 Wangmin362 commented Jun 30, 2026 •

Copy link
Copy Markdown
Member

Part of the HAMi v2.10 roadmap: Project-HAMi/HAMi#1889 (Device Support -- mock-device-plugin support new NPU Template).

What this PR does / why we need it

The mock device plugin had drifted from the device config that the HAMi
scheduler now consumes, so several resources could not be mocked and the
new Ascend vnpus config failed to load. This PR brings it back in line:

  1. Ascend AI-core resource. Newer vnpu configs declare resourceCoreName
    (e.g. huawei.com/Ascend910B4-core) and the scheduler fits vNPU pods on
    the core request, but the mock only registered *-memory. Register the
    AI-core resource as the sum of per-card devcore, falling back to the
    chip-level aiCore when the annotation omits it. memoryFactor is not
    applied to the core resource.

  2. New + legacy vnpus config compatibility. HAMi moved vnpus from a
    flat list to a nested object {hamiVnpuCore, configs: [...]}. The mock
    only understood the flat list and errored out on the new config. Add a
    VNPUs wrapper with a dual-format UnmarshalYAML: prefer the new nested
    object, fall back to the legacy flat list, otherwise return the original
    error. Clusters that have not yet upgraded their device config keep working.

  3. Hygon dcucores resource. HAMi consumes hygon.com/dcucores for DCU
    compute partitioning and the device config sets resourceCoreName by
    default, but the mock only registered dcumem. Register the core resource,
    mirroring nvidia/ascend.

  4. Fix: the Hygon DCU manager never started. RunManager called
    device.Register synchronously, which blocks in its 30s refresh loop and
    prevents the dpm manager (mockmanager.Run) from ever starting, so DCU
    resources were never registered. Run it in a goroutine, matching the
    nvidia and ascend managers.

Also included: unit tests, a per-vendor usage section in the README, a
Makefile with common dev/build/deploy targets, and an optional GOPROXY
Docker build-arg for faster image builds.

How was this validated

  • Unit tests (go test ./... passes): dual-format vnpus parsing (new
    nested, legacy flat, invalid scalar, empty), and core-resource registration
    for ascend and hygon (including the no-resourceCoreName case).
  • Functional validation on a Kubernetes cluster, against two HAMi chart
    versions to exercise both vnpus layouts, for NVIDIA / Ascend / Hygon:
    • v2.9.0 (nested vnpus, ascend entry has resourceCoreName): the mock
      registers both *-memory and *-core; Hygon registers dcumem and
      dcucores; NVIDIA registers gpumem / gpucores / gpumem-percentage.
    • v2.8.1 (legacy flat vnpus, no resourceCoreName): the mock parses
      the legacy format (logging the fallback) and registers *-memory only,
      with no *-core — confirming backward compatibility.
    • In both cases the mocked resources appear in node.status.allocatable,
      and a pod requesting them is scheduled and starts.

Type of change

/kind feature

Release note

mock-device-plugin: register the Ascend AI-core and Hygon dcucores resources, and support both the new nested and the legacy flat `vnpus` device-config formats.

Summary by CodeRabbit

  • New Features
    • Added optional core resource reporting alongside memory for supported mock device plugins (including Ascend and Hygon).
    • Extended Ascend configuration parsing to accept both new nested and legacy YAML formats.
    • Updated build/deploy workflow with a Makefile covering build, test, Docker build/push, and deploy/undeploy.
  • Tests
    • Added unit tests for Ascend node annotation decoding, core-resource derivation, and dual-format YAML unmarshalling.
  • Documentation
    • Expanded the README with a comprehensive mock-plugin usage guide and vendor-specific examples.
  • Chores
    • Improved Docker builds with an overridable Go module proxy and refined build-output ignore rules.

wangmin added 4 commits June 30, 2026 17:36
RunManager called device.Register synchronously, which blocks in its 30s
refresh loop and prevents the dpm manager (mockmanager.Run) from ever
starting, so Hygon DCU resources were never registered. nvidia and ascend
already use 'go device.Register'. (kunlun has the same latent bug but is
not currently wired up.)

Signed-off-by: wangmin <wangmin@riseunion.io>
…config

- Add ResourceCoreName to VNPUConfig and register huawei.com/Ascend{X}-core
  in GetResource: sum of per-card devcore, falling back to the chip-level
  aiCore when the annotation omits it; MemoryFactor is not applied to core.
- Add the VNPUs wrapper {hamiVnpuCore, configs} mirroring upstream HAMi,
  with a dual-format UnmarshalYAML: prefer the new nested object, fall back
  to the legacy flat list, otherwise return the original error.
- Wire config.go to the nested VNPUs and InitDevices(config.VNPUs.Configs).
- Add unit tests for dual-format parsing and core registration.
- README: per-vendor usage guide; Makefile: common dev/build/deploy targets.

Signed-off-by: wangmin <wangmin@riseunion.io>
HAMi consumes hygon.com/dcucores for DCU compute partitioning
(GenerateResourceRequests reads it and the scheduler fits on Coresreq vs
Totalcore), and the device-config sets resourceCoreName by default, but
the mock only registered dcumem. Sum per-card devcore into the core
resource when resourceCoreName is configured, mirroring nvidia/ascend.

Signed-off-by: wangmin <wangmin@riseunion.io>
The image build runs 'go build' inside the container, which downloads all
modules from the default proxy and can be slow on some networks. Add a
GOPROXY build-arg (default unchanged) so it can be overridden, e.g.:
  make docker-build GOPROXY=https://goproxy.cn,direct

Signed-off-by: wangmin <wangmin@riseunion.io>
@hami-robot

hami-robot Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

@Wangmin362: The label(s) kind/feature cannot be applied, because the repository doesn't have them.

Details

In response to this:

What this PR does / why we need it

The mock device plugin had drifted from the device config that the HAMi
scheduler now consumes, so several resources could not be mocked and the
new Ascend vnpus config failed to load. This PR brings it back in line:

  1. Ascend AI-core resource. Newer vnpu configs declare resourceCoreName
    (e.g. huawei.com/Ascend910B4-core) and the scheduler fits vNPU pods on
    the core request, but the mock only registered *-memory. Register the
    AI-core resource as the sum of per-card devcore, falling back to the
    chip-level aiCore when the annotation omits it. memoryFactor is not
    applied to the core resource.

  2. New + legacy vnpus config compatibility. HAMi moved vnpus from a
    flat list to a nested object {hamiVnpuCore, configs: [...]}. The mock
    only understood the flat list and errored out on the new config. Add a
    VNPUs wrapper with a dual-format UnmarshalYAML: prefer the new nested
    object, fall back to the legacy flat list, otherwise return the original
    error. Clusters that have not yet upgraded their device config keep working.

  3. Hygon dcucores resource. HAMi consumes hygon.com/dcucores for DCU
    compute partitioning and the device config sets resourceCoreName by
    default, but the mock only registered dcumem. Register the core resource,
    mirroring nvidia/ascend.

  4. Fix: the Hygon DCU manager never started. RunManager called
    device.Register synchronously, which blocks in its 30s refresh loop and
    prevents the dpm manager (mockmanager.Run) from ever starting, so DCU
    resources were never registered. Run it in a goroutine, matching the
    nvidia and ascend managers.

Also included: unit tests, a per-vendor usage section in the README, a
Makefile with common dev/build/deploy targets, and an optional GOPROXY
Docker build-arg for faster image builds.

How was this validated

  • Unit tests (go test ./... passes): dual-format vnpus parsing (new
    nested, legacy flat, invalid scalar, empty), and core-resource registration
    for ascend and hygon (including the no-resourceCoreName case).
  • Functional validation on a Kubernetes cluster, against two HAMi chart
    versions to exercise both vnpus layouts, for NVIDIA / Ascend / Hygon:
  • v2.9.0 (nested vnpus, ascend entry has resourceCoreName): the mock
    registers both *-memory and *-core; Hygon registers dcumem and
    dcucores; NVIDIA registers gpumem / gpucores / gpumem-percentage.
  • v2.8.1 (legacy flat vnpus, no resourceCoreName): the mock parses
    the legacy format (logging the fallback) and registers *-memory only,
    with no *-core — confirming backward compatibility.
  • In both cases the mocked resources appear in node.status.allocatable,
    and a pod requesting them is scheduled and starts.

Type of change

/kind feature

Release note

mock-device-plugin: register the Ascend AI-core and Hygon dcucores resources, and support both the new nested and the legacy flat `vnpus` device-config formats.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@hami-robot

hami-robot Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Welcome @Wangmin362! It looks like this is your first PR to Project-HAMi/mock-device-plugin 🎉

@coderabbitai

coderabbitai Bot commented Jun 30, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e8f26b0b-35a4-4cba-8b4d-3bdf63c6d8ac

📥 Commits

Reviewing files that changed from the base of the PR and between b50e682 and 44e4ebb.

📒 Files selected for processing (1)
  • internal/pkg/api/device/ascend/device_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/pkg/api/device/ascend/device_test.go

📝 Walkthrough

Walkthrough

Adds optional core resource registration for Ascend and Hygon devices, introduces dual-format vnpus YAML parsing, updates config wiring, and adds Makefile-based build and deployment tooling plus Dockerfile GOPROXY support.

Changes

Core Resource Support and VNPUs Dual-Format

Layer / File(s) Summary
VNPUs dual-format YAML model and config wiring
internal/pkg/api/device/ascend/vnpu.go, internal/pkg/config/config.go, internal/pkg/api/device/ascend/vnpu_test.go, internal/pkg/api/device/ascend/device_test.go
Introduces the VNPUs struct, adds nested-object and legacy flat-list YAML unmarshalling, updates config initialization to use VNPUs.Configs, and updates device initialization tests for the new input shape.
Ascend ResourceCoreName and core accumulation
internal/pkg/api/device/ascend/device.go, internal/pkg/api/device/ascend/device_core_test.go
Adds ResourceCoreName to VNPUConfig and extends GetResource to initialize and accumulate an optional core resource. Tests cover core key presence, annotation parsing, and device decoding.
Hygon core resource and manager launch
internal/pkg/api/device/hygon/device.go, internal/pkg/api/device/hygon/device_test.go
Extends Hygon resource aggregation to include an optional core resource and changes RunManager to register the mock lister in a goroutine. Tests add core-resource assertions and a no-core-name case.

Makefile, Dockerfile GOPROXY, and README

Layer / File(s) Summary
Makefile, Dockerfile GOPROXY, and build ignores
Makefile, Dockerfile, .gitignore
Adds Makefile targets for help, formatting, linting, testing, building, cleaning, docker operations, and deployment. Dockerfile gets configurable GOPROXY, and .gitignore adds bin/.
README rewrite with usage and compatibility
README.md
Expands the README with how the mock plugin works, vendor usage examples, Ascend config compatibility, resource mapping details, and Makefile-based build instructions.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Poem

🐇 I hop through core counts, bright and new,
YAML has two paths, both shining through.
make build thumps softly; make test takes a bow,
The README blooms like a carrot patch now.
With GOPROXY set and resources in sight,
This bunny declares the build feels just right!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: Ascend/Hygon core resource registration and dual-format vnpus config support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@hami-robot hami-robot Bot added the size/XL label Jun 30, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Makefile`:
- Around line 33-39: The Makefile is missing a standard all target alias, which
causes compatibility issues with tooling that expects make all to work. Add a
thin all target that delegates to the existing build target while keeping
.DEFAULT_GOAL := help unchanged, and place it near the other top-level targets
so it is easy to find alongside help and build.

In `@README.md`:
- Around line 107-122: The Hygon DCU docs in the README still only describe
memory and count resources, so update the Hygon walkthrough and related summary
text to include the new core resource name `hygon.com/dcucores` and clarify when
it is exposed. Adjust the Hygon section that mentions `hygon.com/dcumem`, the
config/annotation notes around `hami.io/node-dcu-register`, and any summary
table entries so they reflect both memory and core resource behavior
consistently.
- Around line 14-20: The diagram block in README.md uses an unlabeled fenced
code block, which markdownlint-cli2 flags. Update the fenced block that contains
the node/register diagram to include a language tag, using the existing diagram
content and marking the fence as text so the README stays lint-clean.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ea4a3401-51c2-4815-a387-75c2d9cd955d

📥 Commits

Reviewing files that changed from the base of the PR and between 017d518 and 62aceda.

📒 Files selected for processing (11)
  • .gitignore
  • Dockerfile
  • Makefile
  • README.md
  • internal/pkg/api/device/ascend/device.go
  • internal/pkg/api/device/ascend/device_core_test.go
  • internal/pkg/api/device/ascend/vnpu.go
  • internal/pkg/api/device/ascend/vnpu_test.go
  • internal/pkg/api/device/hygon/device.go
  • internal/pkg/api/device/hygon/device_test.go
  • internal/pkg/config/config.go

Comment thread Makefile
Comment thread README.md Outdated
Comment thread README.md
- README: document hygon.com/dcucores in the Hygon usage section, the
  verify line, and the ManagedResources table (the dcucores change added
  the resource but not the docs).
- README: tag the "How it works" diagram fence as text (markdownlint MD040).
- Makefile: add an 'all: build' alias for standard tooling (checkmake).

Signed-off-by: wangmin <wangmin@riseunion.io>
@Wangmin362

Copy link
Copy Markdown
Member Author

Thanks for the review. Addressed the three CodeRabbit comments in e138184:

  • README – documented hygon.com/dcucores in the Hygon usage section, the verify line, and the ManagedResources table (the dcucores change registered the resource but the docs hadn't been updated).
  • README – tagged the "How it works" diagram fence as text (markdownlint MD040).
  • Makefile – added an all: build alias for standard tooling (checkmake).

The remaining hami-robot note about the kind/feature label is just that the repo doesn't define that label; happy to adjust the label/type if maintainers prefer a different convention.

Disclosure per the AI Assistance Notice: this response and the above changes were prepared with AI assistance and reviewed by me before posting.

@Wangmin362

Copy link
Copy Markdown
Member Author

@archlitchi PTAL!

Comment thread internal/pkg/api/device/ascend/device.go Outdated
Comment thread internal/pkg/api/device/ascend/device.go Outdated
Comment thread internal/pkg/api/device/ascend/vnpu.go Outdated
wangmin added 2 commits June 30, 2026 19:51
huawei.com/<chip>-core is percentage-based: a whole card is 100. HAMi caps
a core request at 100 and, in hami-vnpu-core soft mode, treats a card's
total core as 100 regardless of the physical AI-core count. Register 100 per
physical card instead of the annotation devcore / chip aiCore. Update unit
tests and README accordingly.

Also bump the copyright year on this PR's new files to 2026.

Signed-off-by: wangmin <wangmin@riseunion.io>
huawei.com/<chip>-core is the soft-partition (hami-vnpu-core) core
resource. Previously the mock registered it whenever the chip config set
resourceCoreName, but the default config sets resourceCoreName for every
Ascend chip while vnpus.hamiVnpuCore defaults to false. As a result the
mock advertised -core on hard/template nodes, where the HAMi scheduler
filters out any pod that requests -core (ModeNotFit) -- a dead resource.

Gate -core registration on whether the node runs in hami-vnpu-core mode,
mirroring the real ascend-device-plugin (IsHamiVnpuCore) and the HAMi
scheduler's nodeSupportHamiCore: the node hami-vnpu-core annotation takes
precedence over the global vnpus.hamiVnpuCore config. Thread the global
flag into each ascend Devices via InitDevices.

Add unit tests for global-off, node-annotation override on, and override
off. Update the README to document the mode gating.

Signed-off-by: wangmin <wangmin@riseunion.io>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
internal/pkg/api/device/ascend/device_test.go (1)

96-96: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the new HamiVnpuCore wiring here.

This still only exercises Configs, so a regression where InitDevices stops copying VNPUs.HamiVnpuCore into Devices.hamiVnpuCore would pass unnoticed even though GetResource now depends on that field.

Suggested test extension
 	tests := []struct {
 		name           string
+		hamiVnpuCore   bool
 		configs        []VNPUConfig
 		expectedCount  int
 		expectedCommon []string
 	}{
 		{
 			name: "single device config",
+			hamiVnpuCore: true,
 			configs: []VNPUConfig{
 				{
@@
 		t.Run(tt.name, func(t *testing.T) {
-			devices := InitDevices(VNPUs{Configs: tt.configs})
+			devices := InitDevices(VNPUs{
+				HamiVnpuCore: tt.hamiVnpuCore,
+				Configs:      tt.configs,
+			})
@@
 			for i, dev := range devices {
+				if dev.hamiVnpuCore != tt.hamiVnpuCore {
+					t.Fatalf("device %d: hamiVnpuCore = %v, want %v", i, dev.hamiVnpuCore, tt.hamiVnpuCore)
+				}
 				if tt.expectedCommon[i] != dev.CommonWord() {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/pkg/api/device/ascend/device_test.go` at line 96, Extend the
InitDevices test coverage to include VNPUs.HamiVnpuCore in addition to Configs,
so the wiring into Devices.hamiVnpuCore is validated. Update the test setup
around InitDevices and the related assertions on Devices to confirm the
HamiVnpuCore value is preserved, ensuring GetResource-dependent regressions are
caught. Use the InitDevices, VNPUs, and Devices symbols to locate the code path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/pkg/api/device/ascend/device_test.go`:
- Line 96: Extend the InitDevices test coverage to include VNPUs.HamiVnpuCore in
addition to Configs, so the wiring into Devices.hamiVnpuCore is validated.
Update the test setup around InitDevices and the related assertions on Devices
to confirm the HamiVnpuCore value is preserved, ensuring GetResource-dependent
regressions are caught. Use the InitDevices, VNPUs, and Devices symbols to
locate the code path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d7622a72-9a43-46c1-afd4-fd28d1f78d42

📥 Commits

Reviewing files that changed from the base of the PR and between b996c3a and b50e682.

📒 Files selected for processing (5)
  • README.md
  • internal/pkg/api/device/ascend/device.go
  • internal/pkg/api/device/ascend/device_core_test.go
  • internal/pkg/api/device/ascend/device_test.go
  • internal/pkg/config/config.go
✅ Files skipped from review due to trivial changes (1)
  • README.md

@DSFans2014 DSFans2014 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi @Wangmin362 Have you tested it locally to see if xxx-core resources get reported correctly?

@Wangmin362

Copy link
Copy Markdown
Member Author

hi @Wangmin362 Have you tested it locally to see if xxx-core resources get reported correctly?

Yes. I deployed the open-source HAMi scheduler together with this mock-device-plugin on a Kubernetes cluster and mocked an Ascend node (no real NPU) via the hami.io/node-register- annotation + count resource, then checked node.status.allocatable and the device-plugin logs. Results:

-core value (percentage-based, 100/card): a 2-card register annotation reports …/-memory=65536 and …/-core=200 (2 × 100), independent of the annotation's devcore. ✅

-core gated on hami-vnpu-core mode (node annotation over global vnpus.hamiVnpuCore):

global hamiVnpuCore node hami-vnpu-core anno -core reported?
true – ✅ yes (200)
false – ❌ no (memory only)
false true ✅ yes — annotation overrides global
true false ❌ no — annotation overrides global

dual-format vnpus: verified on both HAMi v2.9.0 (nested {hamiVnpuCore, configs}) → -core reported in soft mode, and v2.8.1 (legacy flat list, no resourceCoreName) → memory only, no -core, with the "parsed as legacy flat-list format" warning logged.

Scheduling: a pod with huawei.com/vnpu-mode: hami-core requesting -core schedules onto a hami-vnpu-core node and starts; on a non-soft node (no -core advertised) the scheduler correctly rejects it with ModeNotFit. NVIDIA/Hygon resources are unaffected.

Unit tests (device_core_test.go) cover all four mode combinations.

Extend TestInitDevices to pass VNPUs.HamiVnpuCore and assert it is copied
into each Devices.hamiVnpuCore, so a regression where InitDevices stops
propagating the flag (which GetResource now depends on) is caught.
Addresses a CodeRabbit review nitpick.

Signed-off-by: wangmin <wangmin@riseunion.io>

@DSFans2014 DSFans2014 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@archlitchi archlitchi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@hami-robot

hami-robot Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: archlitchi, Wangmin362

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@hami-robot hami-robot Bot added the approved label Jul 7, 2026
@hami-robot
hami-robot Bot merged commit d3b1687 into Project-HAMi:master Jul 7, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants