mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-20 00:15:16 +00:00
fix: resolve duplicated tenant-path segment in team shared-workspace resolution (#1322)
Root cause: internal/agent/loop_context.go re-applied tenant scoping (TenantLayer/TenantID) on top of l.dataDir, which was already tenant-scoped upstream in internal/agent/resolver.go, producing paths like /app/workspace/tenants/<slug>/tenants/<slug>/teams/<teamID> instead of the correct /app/workspace/tenants/<slug>/teams/<teamID>. Also consolidates all previously-duplicated tenant-path-joining logic (config.TenantDataDir, config.TenantWorkspace, tools.TenantLayer, workspace.tenantPath) into a single canonical config.TenantScopedDir function in internal/config/tenant_paths.go, with all other implementations now delegating to it. Co-authored-by: Bruno Clermont <bruno.clermont@gmail.com>
This commit is contained in:
1 parent
41321251cb
commit
7d95e4ae01
6 files changed
+196
-54
No files matched your search
@@ -212,9 +212,11 @@ func (l *Loop) injectContext(ctx context.Context, req *RunRequest) (contextSetup
|
||||
ctx = tools.WithToolTeamID(ctx, req.TeamID)
|
||||
// Team root for dispatched tasks: resolve the UserChatLayer-stripped root
|
||||
// so the dispatched agent can still read peer-scoped files in the same team.
|
||||
// l.dataDir is already tenant-scoped (see resolver.go: config.TenantDataDir),
|
||||
// so TenantLayer must NOT be reapplied here — doing so double-joins the
|
||||
// tenant segment (tenants/<slug>/tenants/<slug>/teams/<id>).
|
||||
if teamUUID, err := uuid.Parse(req.TeamID); err == nil && l.dataDir != "" {
|
||||
teamRoot := tools.ResolveWorkspace(l.dataDir,
|
||||
tools.TenantLayer(store.TenantIDFromContext(ctx), store.TenantSlugFromContext(ctx)),
|
||||
tools.TeamLayer(teamUUID),
|
||||
)
|
||||
ctx = tools.WithToolTeamRoot(ctx, teamRoot)
|
||||
@@ -244,9 +246,10 @@ func (l *Loop) injectContext(ctx context.Context, req *RunRequest) (contextSetup
|
||||
wsChat = req.UserID
|
||||
}
|
||||
shared := tools.IsSharedWorkspace(team.Settings)
|
||||
// Resolve team workspace via layered pipeline: tenant → team → user/chat.
|
||||
// Resolve team workspace via layered pipeline: team → user/chat.
|
||||
// l.dataDir is already tenant-scoped (see resolver.go: config.TenantDataDir) —
|
||||
// do NOT reapply TenantLayer here, it would double-join the tenant segment.
|
||||
wsDir := tools.ResolveWorkspace(l.dataDir,
|
||||
tools.TenantLayer(store.TenantIDFromContext(ctx), store.TenantSlugFromContext(ctx)),
|
||||
tools.TeamLayer(team.ID),
|
||||
tools.UserChatLayer(wsChat, shared),
|
||||
)
|
||||
@@ -264,7 +267,6 @@ func (l *Loop) injectContext(ctx context.Context, req *RunRequest) (contextSetup
|
||||
// the same team. Writes still default to wsDir above; team root only
|
||||
// widens the allowed-prefix set for path boundary checks.
|
||||
teamRoot := tools.ResolveWorkspace(l.dataDir,
|
||||
tools.TenantLayer(store.TenantIDFromContext(ctx), store.TenantSlugFromContext(ctx)),
|
||||
tools.TeamLayer(team.ID),
|
||||
)
|
||||
ctx = tools.WithToolTeamRoot(ctx, teamRoot)
|
||||
@@ -294,12 +296,14 @@ func (l *Loop) injectContext(ctx context.Context, req *RunRequest) (contextSetup
|
||||
// Filesystem path segment must use agent_key, not UUID — matches
|
||||
// the v2 path in loop_pipeline_callbacks.go and the session_key
|
||||
// anchor. See docs/agent-identity-conventions.md.
|
||||
AgentID: l.id,
|
||||
AgentType: l.agentType,
|
||||
UserID: req.UserID,
|
||||
ChatID: req.ChatID,
|
||||
TenantID: store.TenantIDFromContext(ctx).String(),
|
||||
TenantSlug: store.TenantSlugFromContext(ctx),
|
||||
AgentID: l.id,
|
||||
AgentType: l.agentType,
|
||||
UserID: req.UserID,
|
||||
ChatID: req.ChatID,
|
||||
// TenantID/TenantSlug intentionally left empty: l.dataDir (BaseDir below)
|
||||
// is already tenant-scoped (see resolver.go: config.TenantDataDir). Setting
|
||||
// TenantID here would make resolveTeam/resolvePersonal reapply tenantPath()
|
||||
// and double-join the tenant segment (tenants/<slug>/tenants/<slug>/...).
|
||||
PeerKind: req.PeerKind,
|
||||
TeamID: teamIDPtr,
|
||||
TeamConfig: teamWSConfig,
|
||||
|
||||
Reference in new issue
Block a user