Skip to content

fix: pass workspace from YAML import to agent definition#35

Open
dajiaohuang wants to merge 3 commits into
chaitin:mainfrom
dajiaohuang:fix/33-yaml-import-workspace
Open

fix: pass workspace from YAML import to agent definition#35
dajiaohuang wants to merge 3 commits into
chaitin:mainfrom
dajiaohuang:fix/33-yaml-import-workspace

Conversation

@dajiaohuang

@dajiaohuang dajiaohuang commented Jun 20, 2026

Copy link
Copy Markdown

Summary

When importing a project via YAML, the workspace was parsed and stored in the normalized spec but never bound to the agent. AgentDefinition.WorkspaceID was always empty, so agents started in an empty directory.

Agent-level workspace takes precedence; project-level workspace is used as fallback.

Testing

go build ./pkg/compose/ and go build ./pkg/agentcompose/ pass.

Checklist

  • Documentation updated when behavior or configuration changed.
  • Tests added or updated for user-visible behavior.
  • No secrets, private endpoints, internal certificates, or local runtime state included.

Fixes #33

When importing a project via YAML, the workspace was parsed and
stored in the normalized spec but never bound to the agent. The
AgentDefinition.WorkspaceID was always empty, so agents started
in an empty directory.

Resolve workspace from agent-level spec first, falling back to
project-level. Generate a deterministic workspace ID from the
spec fields so repeated imports do not create duplicates.

Fixes chaitin#33
@eetoc

eetoc commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the fix. The direction makes sense to me: YAML-imported managed agents should not lose the workspace declared in the project spec, especially when the managed agent is started outside the project-run path.

One thing I am not fully sure about from this patch: projectManagedAgentDefinitionFromSpec now fills AgentDefinition.WorkspaceID with a deterministic ID, but I could not find where ApplyProject creates or upserts a matching WorkspaceConfig for that ID. Later, agent validation / CreateAgentSession resolves WorkspaceID through GetWorkspaceConfig, so if the config row does not exist the managed agent may show as unavailable with workspace config <id> not found.

Project runs already seem to materialize workspace from the project revision spec at run time, so this mainly matters for using the imported managed agent through the normal agent-definition/session path.

Could we confirm that the matching workspace config is persisted somewhere, or add that as part of this change? A regression test that applies a project with project-level + agent-level workspace and then verifies the managed agent workspace resolves successfully would make this much clearer.

@eetoc

eetoc commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Following up on the workspace persistence concern above.

I think this still needs a small but important follow-up before the PR can land: the managed AgentDefinition now gets a deterministic WorkspaceID, but I still cannot find where ApplyProject creates or upserts the matching WorkspaceConfig. Since CreateAgentSession validates that WorkspaceID through GetWorkspaceConfig, the imported managed agent may fail with workspace config <id> not found.

Could you take another look and either point me to the persistence path I missed, or update the PR to materialize/upsert the workspace config and add a regression test for ApplyProject -> managed AgentDefinition -> CreateAgentSession? Happy to re-review once updated.

When importing a project via YAML with a workspace, the agent definition
gets a deterministic WorkspaceID but the matching WorkspaceConfig was
never created.  CreateAgentSession validates WorkspaceID existence via
GetWorkspaceConfig, so the imported agent would fail with "workspace
config <id> not found".

This change:
- Adds UpsertWorkspaceConfig to ConfigStore for idempotent persistence
- Materializes WorkspaceConfig rows during ApplyProject before agent
  definitions are reconciled
- Deduplicates by StableWorkspaceID so re-imports are safe

Fixes chaitin#33
@dajiaohuang

Copy link
Copy Markdown
Author

Thanks for the careful review. The gap you identified is real — the WorkspaceID was stored on AgentDefinition but the matching WorkspaceConfig row was never persisted, so CreateAgentSession (via agentWorkspaceGetWorkspaceConfig) would fail to resolve it.

What was fixed:

  • config_store.go: Added getWorkspaceConfigIfExists helper and UpsertWorkspaceConfig method (follows the same pattern as UpsertManagedAgentDefinition).
  • project_service.go: Added projectWorkspaceConfigFromSpec (converts WorkspaceSpecWorkspaceConfig using the deterministic StableWorkspaceID) and upsertProjectWorkspaceConfigs (collects unique workspace specs across agents, agent-level first then project-level fallback, and upserts each). Called in ApplyProject after records are rebuilt with the revision and before agent definitions are reconciled.
  • project_service_test.go: Added TestProjectServiceApplyProjectUpsertsWorkspaceConfigs — tests git workspace persistence, idempotency on re-apply, and agent-level override vs project-level fallback.

The workspace config created during apply uses the same deterministic StableWorkspaceID that the agent definition references, so repeated YAML imports are idempotent (Update preserves CreatedAt, Insert creates if missing).

@eetoc

eetoc commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

I took another look at the latest fix. The overall direction makes sense: once the managed agent stores a stable workspace id, ApplyProject does need to materialize the matching workspace config. There are two details that may still need a bit more adjustment though:

  1. The newly added test currently fails. In TestProjectServiceApplyProjectUpsertsWorkspaceConfigs, the project workspace only provides url/branch/path without provider, but the test expects the persisted workspace to be a git workspace. In practice, projectWorkspaceConfigFromSpec currently treats an empty provider as the local/file branch, so the failure is:
workspace config type = "file", want git

Repro:

go test ./pkg/agentcompose -run 'TestProjectServiceApplyProjectUpsertsWorkspaceConfigs' -count=1

It may be worth making the semantics explicit here: either the API/test should always send provider: git, or the conversion layer should infer git when a workspace has a URL. Otherwise, a git workspace applied through the API can be persisted as a file workspace.

  1. For provider: local, the apply path currently creates a default file workspace config, but it does not snapshot/copy the local directory from the compose source path the way project run workspace preparation does. That means the managed agent session can pass workspace validation, but may start with an empty file workspace instead of the content pointed to by the YAML path.

I also ran:

go test ./pkg/compose

That one passes. Once the two workspace handling details above are addressed, this PR should be in much better shape.

- Auto-detect git provider from URL presence when provider is empty
  so that workspace specs with url/branch/path but no explicit
  provider resolve to type 'git' instead of 'file'.

- Snapshot local workspace source directory into the file workspace
  content root during project apply so that agent sessions start
  with the project files rather than an empty directory.

- Add test coverage for git auto-detection and local workspace
  content population.

Co-Authored-By: Claude <noreply@anthropic.com>
@dajiaohuang

Copy link
Copy Markdown
Author

Hey @eetoc, thanks for the review! I have addressed both issues you raised:

1. Provider type mismatch (#35 (comment))

Added auto-detection: when provider is empty but url is present, projectWorkspaceConfigFromSpec now automatically resolves to "git" instead of falling through to "file". This means users do not need to specify provider: git explicitly when a URL is present.

Added test coverage in TestProjectServiceApplyProjectUpsertsWorkspaceConfigs — both auto-detected and explicit provider: git are verified.

2. Local workspace not populated

For provider: local, the function now snapshots the source directory into the file workspace content root during ApplyProject. This follows the same pattern as materializeLocalProjectRunWorkspace (in run_preparation.go) but uses the stable workspace ID so that re-imports are safe. Agent sessions will now start with the project files instead of an empty directory.

Added TestProjectServiceApplyProjectUpsertsLocalWorkspaceContent — creates a project dir with test files, applies a project with provider: local, and verifies the workspace content root contains the expected files.

go build ./pkg/compose/ passes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: 通过 YAML 导入项目时,工作区没有真正绑定到智能体。

2 participants