diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 05f04cd12307824734018604f4a5faf7469830ad..7f8d2dc4277bf01b9c2e9c83afad722682e240c1 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -14677,22 +14677,12 @@ An AI agent.
 
 | Name | Type | Description |
 | ---- | ---- | ----------- |
-| <a id="aiagent_links"></a>`_links` | [`AiAgentLinks!`](#aiagentlinks) | Map of links to perform actions on the agent. |
 | <a id="aiagentcreatedat"></a>`createdAt` | [`Time!`](#time) | Date of creation. |
 | <a id="aiagentid"></a>`id` | [`ID!`](#id) | ID of the agent. |
 | <a id="aiagentname"></a>`name` | [`String!`](#string) | Name of the agent. |
+| <a id="aiagentrouteid"></a>`routeId` | [`Int!`](#int) | Route ID of the agent. |
 | <a id="aiagentversions"></a>`versions` | [`[AiAgentVersion!]`](#aiagentversion) | Versions of the agent. |
 
-### `AiAgentLinks`
-
-Represents links to perform actions on the agent.
-
-#### Fields
-
-| Name | Type | Description |
-| ---- | ---- | ----------- |
-| <a id="aiagentlinksshowpath"></a>`showPath` | [`String`](#string) | Path to the details page of the agent. |
-
 ### `AiAgentVersion`
 
 Version of an AI Agent.
diff --git a/ee/app/assets/javascripts/ml/ai_agents/apps/index.js b/ee/app/assets/javascripts/ml/ai_agents/apps/index.js
deleted file mode 100644
index fd49e5da3c5201f3cfee984dd7764050e226f3ad..0000000000000000000000000000000000000000
--- a/ee/app/assets/javascripts/ml/ai_agents/apps/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import ListAgents from './list_agents.vue';
-import CreateAgent from './create_agent.vue';
-import ShowAgent from './show_agent.vue';
-
-export { ListAgents, CreateAgent, ShowAgent };
diff --git a/ee/app/assets/javascripts/ml/ai_agents/base_app.vue b/ee/app/assets/javascripts/ml/ai_agents/base_app.vue
new file mode 100644
index 0000000000000000000000000000000000000000..982f701b95f040e47534553e0d4b8c824ba70a98
--- /dev/null
+++ b/ee/app/assets/javascripts/ml/ai_agents/base_app.vue
@@ -0,0 +1,3 @@
+<template>
+  <router-view ref="router-view" />
+</template>
diff --git a/ee/app/assets/javascripts/ml/ai_agents/components/agent_list.vue b/ee/app/assets/javascripts/ml/ai_agents/components/agent_list.vue
index 1d89ce9fcfa1852a870e127e24326b0f58017495..9edd37e1d0e293383ae89f5572dc2775f4449427 100644
--- a/ee/app/assets/javascripts/ml/ai_agents/components/agent_list.vue
+++ b/ee/app/assets/javascripts/ml/ai_agents/components/agent_list.vue
@@ -1,25 +1,19 @@
 <script>
-import { GlLink, GlLoadingIcon, GlTableLite, GlEmptyState } from '@gitlab/ui';
+import { GlLoadingIcon, GlTableLite, GlEmptyState } from '@gitlab/ui';
 import * as Sentry from '~/sentry/sentry_browser_wrapper';
 import { s__ } from '~/locale';
+import { ROUTE_SHOW_AGENT } from '../constants';
 import getAiAgents from '../graphql/queries/get_ai_agents.query.graphql';
 
 const GRAPHQL_PAGE_SIZE = 30;
 
 export default {
   components: {
-    GlLink,
     GlLoadingIcon,
     GlEmptyState,
     GlTableLite,
   },
   inject: ['projectPath'],
-  props: {
-    createAgentPath: {
-      type: String,
-      required: true,
-    },
-  },
   data() {
     return {
       agents: {},
@@ -30,7 +24,6 @@ export default {
     emptyState: {
       title: s__('AiAgents|Create your own AI Agents'),
       description: s__('AiAgents|Create and manage your AI Agents'),
-      createNew: s__('AiAgents|Get started'),
       svgPath: '/assets/illustrations/tanuki_ai_logo.svg',
     },
   },
@@ -72,6 +65,7 @@ export default {
       return this.agents?.nodes ?? [];
     },
   },
+  ROUTE_SHOW_AGENT,
   methods: {
     fetchPage(pageInfo) {
       const variables = {
@@ -106,17 +100,19 @@ export default {
       data-testId="aiAgentsTable"
     >
       <template #cell(name)="{ item }">
-        <gl-link :href="item._links.showPath" class="gl-text-body gl-line-height-24">
+        <router-link
+          :to="{ name: $options.ROUTE_SHOW_AGENT, params: { agentId: item.routeId } }"
+          data-testid="agent-item"
+          class="gl-text-body gl-line-height-24"
+        >
           {{ item.name }}
-        </gl-link>
+        </router-link>
       </template>
     </gl-table-lite>
 
     <gl-empty-state
       v-else
       :title="$options.i18n.emptyState.title"
-      :primary-button-text="$options.i18n.emptyState.createNew"
-      :primary-button-link="createAgentPath"
       :svg-path="$options.i18n.emptyState.svgPath"
       :svg-height="null"
       :description="$options.i18n.emptyState.description"
diff --git a/ee/app/assets/javascripts/ml/ai_agents/constants.js b/ee/app/assets/javascripts/ml/ai_agents/constants.js
new file mode 100644
index 0000000000000000000000000000000000000000..1b491ac05e20c5abe3e74e09605bf5457ac32d56
--- /dev/null
+++ b/ee/app/assets/javascripts/ml/ai_agents/constants.js
@@ -0,0 +1,3 @@
+export const ROUTE_LIST_AGENTS = 'list';
+export const ROUTE_NEW_AGENT = 'create';
+export const ROUTE_SHOW_AGENT = 'show';
diff --git a/ee/app/assets/javascripts/ml/ai_agents/graphql/mutations/create_ai_agent.mutation.graphql b/ee/app/assets/javascripts/ml/ai_agents/graphql/mutations/create_ai_agent.mutation.graphql
index 76f9c9e129686418d15a46840a761188e754347b..e9ce1b7c6c17adfdeff03f38a71116179a7f20f7 100644
--- a/ee/app/assets/javascripts/ml/ai_agents/graphql/mutations/create_ai_agent.mutation.graphql
+++ b/ee/app/assets/javascripts/ml/ai_agents/graphql/mutations/create_ai_agent.mutation.graphql
@@ -2,9 +2,7 @@ mutation createAiAgent($projectPath: ID!, $name: String!, $prompt: String!) {
   aiAgentCreate(input: { projectPath: $projectPath, name: $name, prompt: $prompt }) {
     agent {
       id
-      _links {
-        showPath
-      }
+      routeId
     }
     errors
   }
diff --git a/ee/app/assets/javascripts/ml/ai_agents/graphql/queries/get_ai_agents.query.graphql b/ee/app/assets/javascripts/ml/ai_agents/graphql/queries/get_ai_agents.query.graphql
index b9e5f4f3f8cc1acffa51387de38b900c12e8b524..c811900ef2abecc373613cd3d0a6eb67cbaaf062 100644
--- a/ee/app/assets/javascripts/ml/ai_agents/graphql/queries/get_ai_agents.query.graphql
+++ b/ee/app/assets/javascripts/ml/ai_agents/graphql/queries/get_ai_agents.query.graphql
@@ -6,14 +6,12 @@ query getAiAgents($fullPath: ID!, $first: Int, $last: Int, $after: String, $befo
     aiAgents(after: $after, before: $before, first: $first, last: $last) {
       nodes {
         id
+        routeId
         name
         versions {
           id
           model
         }
-        _links {
-          showPath
-        }
       }
       pageInfo {
         ...PageInfo
diff --git a/ee/app/assets/javascripts/ml/ai_agents/index.js b/ee/app/assets/javascripts/ml/ai_agents/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..1d62f12aa75eecec27e34da4c3181342535a4565
--- /dev/null
+++ b/ee/app/assets/javascripts/ml/ai_agents/index.js
@@ -0,0 +1,36 @@
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
+import createRouter from './router';
+import BaseApp from './base_app.vue';
+
+Vue.use(VueApollo);
+
+export default () => {
+  const el = document.getElementById('js-mount-index-ml-agents');
+
+  if (!el) {
+    return false;
+  }
+
+  const { basePath, projectPath } = el.dataset;
+
+  const apolloProvider = new VueApollo({
+    defaultClient: createDefaultClient(),
+  });
+
+  const router = createRouter(basePath);
+
+  return new Vue({
+    el,
+    name: 'AiAgents',
+    apolloProvider,
+    router,
+    provide: {
+      projectPath,
+    },
+    render(h) {
+      return h(BaseApp);
+    },
+  });
+};
diff --git a/ee/app/assets/javascripts/ml/ai_agents/router.js b/ee/app/assets/javascripts/ml/ai_agents/router.js
new file mode 100644
index 0000000000000000000000000000000000000000..e384cb49e4e71f46ec9b7d9d0f3a1ff2c3f5938b
--- /dev/null
+++ b/ee/app/assets/javascripts/ml/ai_agents/router.js
@@ -0,0 +1,34 @@
+import Vue from 'vue';
+import VueRouter from 'vue-router';
+import ListAgents from 'ee/ml/ai_agents/views/list_agents.vue';
+import ShowAgent from 'ee/ml/ai_agents/views/show_agent.vue';
+import CreateAgent from 'ee/ml/ai_agents/views/create_agent.vue';
+import { ROUTE_LIST_AGENTS, ROUTE_NEW_AGENT, ROUTE_SHOW_AGENT } from './constants';
+
+Vue.use(VueRouter);
+
+export default function createRouter(base) {
+  const router = new VueRouter({
+    base,
+    mode: 'history',
+    routes: [
+      {
+        name: ROUTE_LIST_AGENTS,
+        path: '/',
+        component: ListAgents,
+      },
+      {
+        name: ROUTE_NEW_AGENT,
+        path: '/new',
+        component: CreateAgent,
+      },
+      {
+        name: ROUTE_SHOW_AGENT,
+        path: '/:agentId',
+        component: ShowAgent,
+      },
+    ],
+  });
+
+  return router;
+}
diff --git a/ee/app/assets/javascripts/ml/ai_agents/apps/create_agent.vue b/ee/app/assets/javascripts/ml/ai_agents/views/create_agent.vue
similarity index 90%
rename from ee/app/assets/javascripts/ml/ai_agents/apps/create_agent.vue
rename to ee/app/assets/javascripts/ml/ai_agents/views/create_agent.vue
index 0b94b33c15ce052451c8fc45f4dff12738eaf47c..3cc9658a2048f37e8e54cf4c2dcb1f2a83840f49 100644
--- a/ee/app/assets/javascripts/ml/ai_agents/apps/create_agent.vue
+++ b/ee/app/assets/javascripts/ml/ai_agents/views/create_agent.vue
@@ -11,7 +11,6 @@ import {
 import { s__ } from '~/locale';
 import TitleArea from '~/vue_shared/components/registry/title_area.vue';
 import { helpPagePath } from '~/helpers/help_page_helper';
-import { visitUrl } from '~/lib/utils/url_utility';
 import * as Sentry from '~/sentry/sentry_browser_wrapper';
 import createAiAgent from '../graphql/mutations/create_ai_agent.mutation.graphql';
 
@@ -27,12 +26,7 @@ export default {
     GlButton,
     GlAlert,
   },
-  props: {
-    projectPath: {
-      type: String,
-      required: true,
-    },
-  },
+  inject: ['projectPath'],
   data() {
     return {
       errorMessage: undefined,
@@ -60,7 +54,10 @@ export default {
         if (error) {
           this.errorMessage = data.aiAgentCreate.errors.join(', ');
         } else {
-          visitUrl(data?.aiAgentCreate?.agent?._links?.showPath);
+          this.$router.push({
+            name: 'show',
+            params: { agentId: data?.aiAgentCreate?.agent?.routeId },
+          });
         }
       } catch (error) {
         Sentry.captureException(error);
@@ -89,7 +86,7 @@ export default {
 
     <gl-form @submit.prevent="createAgent">
       <gl-form-group :label="s__('AIAgents|Agent name')">
-        <gl-form-input v-model="agentName" />
+        <gl-form-input v-model="agentName" data-testid="agent-name" />
       </gl-form-group>
 
       <gl-form-group :label="__('Prompt')" optional>
diff --git a/ee/app/assets/javascripts/ml/ai_agents/apps/list_agents.vue b/ee/app/assets/javascripts/ml/ai_agents/views/list_agents.vue
similarity index 73%
rename from ee/app/assets/javascripts/ml/ai_agents/apps/list_agents.vue
rename to ee/app/assets/javascripts/ml/ai_agents/views/list_agents.vue
index 6b536f720fc272cd45e8c59ad9ae8e75642e4380..e08e10eac924340ef538494501fbbc0edb5fdee1 100644
--- a/ee/app/assets/javascripts/ml/ai_agents/apps/list_agents.vue
+++ b/ee/app/assets/javascripts/ml/ai_agents/views/list_agents.vue
@@ -1,8 +1,9 @@
 <script>
-import { GlBadge, GlButton } from '@gitlab/ui';
+import { GlBadge } from '@gitlab/ui';
 import TitleArea from '~/vue_shared/components/registry/title_area.vue';
 import { helpPagePath } from '~/helpers/help_page_helper';
 import AgentList from '../components/agent_list.vue';
+import { ROUTE_NEW_AGENT } from '../constants';
 
 export default {
   name: 'ListAiAgents',
@@ -10,29 +11,20 @@ export default {
     TitleArea,
     AgentList,
     GlBadge,
-    GlButton,
   },
   provide() {
     return {
       projectPath: this.projectPath,
     };
   },
-  props: {
-    projectPath: {
-      type: String,
-      required: true,
-    },
-    createAgentPath: {
-      type: String,
-      required: true,
-    },
-  },
+  inject: ['projectPath'],
   data() {
     return {
       errorMessage: undefined,
     };
   },
   helpPagePath: helpPagePath('policy/experiment-beta-support', { anchor: 'experiment' }),
+  ROUTE_NEW_AGENT,
 };
 </script>
 
@@ -48,10 +40,15 @@ export default {
         </div>
       </template>
       <template #right-actions>
-        <gl-button :href="createAgentPath">{{ s__('AIAgents|Create agent') }}</gl-button>
+        <router-link
+          :to="{ name: $options.ROUTE_NEW_AGENT }"
+          class="btn btn-confirm btn-md gl-button"
+        >
+          {{ s__('AIAgents|Create agent') }}
+        </router-link>
       </template>
     </title-area>
 
-    <agent-list :create-agent-path="createAgentPath" />
+    <agent-list />
   </div>
 </template>
diff --git a/ee/app/assets/javascripts/ml/ai_agents/apps/show_agent.vue b/ee/app/assets/javascripts/ml/ai_agents/views/show_agent.vue
similarity index 81%
rename from ee/app/assets/javascripts/ml/ai_agents/apps/show_agent.vue
rename to ee/app/assets/javascripts/ml/ai_agents/views/show_agent.vue
index a1a264ccd0e42bf9ecdae97045d929151f49132d..ea1712171e19f52e591d8ab830fd7b9f91f6257d 100644
--- a/ee/app/assets/javascripts/ml/ai_agents/apps/show_agent.vue
+++ b/ee/app/assets/javascripts/ml/ai_agents/views/show_agent.vue
@@ -14,19 +14,10 @@ export default {
       projectPath: this.projectPath,
     };
   },
-  props: {
-    projectPath: {
-      type: String,
-      required: true,
-    },
-    agentId: {
-      type: String,
-      required: true,
-    },
-  },
+  inject: ['projectPath'],
   computed: {
     title() {
-      return sprintf(s__('AIAgent|AI Agent: %{agentId}'), { agentId: this.agentId });
+      return sprintf(s__('AIAgent|AI Agent: %{agentId}'), { agentId: this.$route.params.agentId });
     },
   },
 };
diff --git a/ee/app/assets/javascripts/pages/projects/ml/agents/index.js b/ee/app/assets/javascripts/pages/projects/ml/agents/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..39b998f32ae4291cb9e3d0b0ec00839a9c239755
--- /dev/null
+++ b/ee/app/assets/javascripts/pages/projects/ml/agents/index.js
@@ -0,0 +1,3 @@
+import initMlAiAgents from 'ee/ml/ai_agents';
+
+initMlAiAgents();
diff --git a/ee/app/assets/javascripts/pages/projects/ml/agents/index/index.js b/ee/app/assets/javascripts/pages/projects/ml/agents/index/index.js
deleted file mode 100644
index cea34c0e7ed04dc84ce21dc2878a892b9d286c33..0000000000000000000000000000000000000000
--- a/ee/app/assets/javascripts/pages/projects/ml/agents/index/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import { initSimpleApp } from '~/helpers/init_simple_app_helper';
-import { ListAgents } from 'ee/ml/ai_agents/apps';
-
-initSimpleApp('#js-mount-index-ml-agents', ListAgents, { withApolloProvider: true });
diff --git a/ee/app/assets/javascripts/pages/projects/ml/agents/new/index.js b/ee/app/assets/javascripts/pages/projects/ml/agents/new/index.js
deleted file mode 100644
index 72fdad4d653b7592f32f9e6cab94f2253e18f136..0000000000000000000000000000000000000000
--- a/ee/app/assets/javascripts/pages/projects/ml/agents/new/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import { initSimpleApp } from '~/helpers/init_simple_app_helper';
-import { CreateAgent } from 'ee/ml/ai_agents/apps';
-
-initSimpleApp('#js-mount-new-ml-agent', CreateAgent, { withApolloProvider: true });
diff --git a/ee/app/assets/javascripts/pages/projects/ml/agents/show/index.js b/ee/app/assets/javascripts/pages/projects/ml/agents/show/index.js
deleted file mode 100644
index 8a9370df8a5a537c387361b5c61729f8900fc79a..0000000000000000000000000000000000000000
--- a/ee/app/assets/javascripts/pages/projects/ml/agents/show/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import { initSimpleApp } from '~/helpers/init_simple_app_helper';
-import { ShowAgent } from 'ee/ml/ai_agents/apps';
-
-initSimpleApp('#js-mount-show-ml-agent', ShowAgent, { withApolloProvider: true });
diff --git a/ee/app/controllers/projects/ml/agents_controller.rb b/ee/app/controllers/projects/ml/agents_controller.rb
index 6de7b9c4d466eefa6d2c43be3dd95d3624bab6d7..132fa556bb9477f85a336d5c68732e2837635f0e 100644
--- a/ee/app/controllers/projects/ml/agents_controller.rb
+++ b/ee/app/controllers/projects/ml/agents_controller.rb
@@ -4,29 +4,16 @@ module Projects
   module Ml
     class AgentsController < Projects::ApplicationController
       before_action :authorize_read_ai_agents!
-      before_action :authorize_write_ai_agents!, only: [:new]
 
       feature_category :mlops
 
-      MAX_MODELS_PER_PAGE = 20
-
       def index; end
 
-      def new; end
-
-      def show
-        @agent_id = params[:agent_id]
-      end
-
       private
 
       def authorize_read_ai_agents!
         render_404 unless can?(current_user, :read_ai_agents, @project)
       end
-
-      def authorize_write_ai_agents!
-        render_404 unless can?(current_user, :write_ai_agents, @project)
-      end
     end
   end
 end
diff --git a/ee/app/graphql/types/ai/agents/agent_links_type.rb b/ee/app/graphql/types/ai/agents/agent_links_type.rb
deleted file mode 100644
index 3fb94a24c03be065d34680f57f5515953c980feb..0000000000000000000000000000000000000000
--- a/ee/app/graphql/types/ai/agents/agent_links_type.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-module Types
-  module Ai
-    module Agents
-      # rubocop: disable Graphql/AuthorizeTypes -- authorization in resolver/mutation
-      class AgentLinksType < Types::BaseObject
-        graphql_name 'AiAgentLinks'
-        description 'Represents links to perform actions on the agent'
-
-        present_using ::Ai::AgentPresenter
-
-        field :show_path, GraphQL::Types::String,
-          null: true,
-          description: 'Path to the details page of the agent.',
-          method: :path
-      end
-      # rubocop: enable Graphql/AuthorizeTypes
-    end
-  end
-end
diff --git a/ee/app/graphql/types/ai/agents/agent_type.rb b/ee/app/graphql/types/ai/agents/agent_type.rb
index 65fb939a7964105568005e13364506cb8c3077c4..b31338fae427ab7b241d09d6f4bc0bfdd57b41f1 100644
--- a/ee/app/graphql/types/ai/agents/agent_type.rb
+++ b/ee/app/graphql/types/ai/agents/agent_type.rb
@@ -10,11 +10,10 @@ class AgentType < ::Types::BaseObject
 
         present_using ::Ai::AgentPresenter
 
-        field :_links, ::Types::Ai::Agents::AgentLinksType, null: false, method: :itself,
-          description: 'Map of links to perform actions on the agent.'
         field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
         field :id, GraphQL::Types::ID, null: false, description: 'ID of the agent.'
         field :name, GraphQL::Types::String, null: false, description: 'Name of the agent.'
+        field :route_id, GraphQL::Types::Int, null: false, description: 'Route ID of the agent.'
         field :versions, [Types::Ai::Agents::AgentVersionType], null: true, description: 'Versions of the agent.'
       end
       # rubocop: enable Graphql/AuthorizeTypes
diff --git a/ee/app/presenters/ai/agent_presenter.rb b/ee/app/presenters/ai/agent_presenter.rb
index cca6ad4702df1a56f61611653365e80351378460..eb82eb2854087696535f8a05ca76f93307c64b59 100644
--- a/ee/app/presenters/ai/agent_presenter.rb
+++ b/ee/app/presenters/ai/agent_presenter.rb
@@ -4,8 +4,8 @@ module Ai
   class AgentPresenter < Gitlab::View::Presenter::Delegated
     presents ::Ai::Agent, as: :agent
 
-    def path
-      project_ml_agent_path(agent.project, agent.id)
+    def route_id
+      agent.id
     end
   end
 end
diff --git a/ee/app/views/projects/ml/agents/index.html.haml b/ee/app/views/projects/ml/agents/index.html.haml
index 09c79773255761fe41efbb35aadff5c33cb21c62..615276826cd0b176cd1374bf7df42589a19bda1d 100644
--- a/ee/app/views/projects/ml/agents/index.html.haml
+++ b/ee/app/views/projects/ml/agents/index.html.haml
@@ -1,6 +1,4 @@
 - breadcrumb_title s_('AIAgents|AI Agents')
 - page_title s_('AIAgents|AI Agents')
-- create_agent_path = new_project_ml_agent_path(@project)
-- view_model = Gitlab::Json.generate({ projectPath: @project.full_path, createAgentPath: create_agent_path })
 
-#js-mount-index-ml-agents{ data: { view_model: view_model } }
+#js-mount-index-ml-agents{ data: { project_path: @project.full_path, base_path: namespace_project_ml_agents_path(@project.namespace, @project) } }
diff --git a/ee/app/views/projects/ml/agents/new.html.haml b/ee/app/views/projects/ml/agents/new.html.haml
deleted file mode 100644
index 7bb7166c61bf2eed39d9f56df70d867819e20c1b..0000000000000000000000000000000000000000
--- a/ee/app/views/projects/ml/agents/new.html.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-- breadcrumb_title s_('AIAgents|AI Agents')
-- page_title s_('AIAgents|New AI Agent')
-- view_model = Gitlab::Json.generate({ projectPath: @project.full_path })
-
-#js-mount-new-ml-agent{ data: { view_model: view_model } }
diff --git a/ee/app/views/projects/ml/agents/show.html.haml b/ee/app/views/projects/ml/agents/show.html.haml
deleted file mode 100644
index 1885c90bee4476ce36dab1d8c2bbd451c48a01a3..0000000000000000000000000000000000000000
--- a/ee/app/views/projects/ml/agents/show.html.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-- breadcrumb_title s_('AiAgents|AI Agents')
-- page_title s_('AiAgents|AI agent')
-- view_model = Gitlab::Json.generate({ projectPath: @project.full_path, agentId: @agent_id })
-
-#js-mount-show-ml-agent{ data: { view_model: view_model } }
diff --git a/ee/config/routes/project.rb b/ee/config/routes/project.rb
index 7620d24eb335858131180758c3e181712c90a7d4..986a51f8bc6ef141dad9f41b012c2d4af7a90e7a 100644
--- a/ee/config/routes/project.rb
+++ b/ee/config/routes/project.rb
@@ -156,7 +156,7 @@
         resources :logs, only: [:index], controller: :logs
 
         namespace :ml do
-          resources :agents, only: [:index, :new, :show], controller: 'agents', param: :agent_id
+          resources :agents, path: 'agents(/*vueroute)', action: :index
         end
       end
       # End of the /-/ scope.
diff --git a/ee/spec/controllers/projects/ml/agents_controller_spec.rb b/ee/spec/controllers/projects/ml/agents_controller_spec.rb
index 6bf30203fee85f5f652c728862be6254f5f36608..1f5131988f7bf72755d07297378a9ee85f6d4fed 100644
--- a/ee/spec/controllers/projects/ml/agents_controller_spec.rb
+++ b/ee/spec/controllers/projects/ml/agents_controller_spec.rb
@@ -7,16 +7,12 @@
   let_it_be(:user) { project.first_owner }
 
   let(:read_ai_agents) { true }
-  let(:write_ai_agents) { true }
 
   before do
     allow(Ability).to receive(:allowed?).and_call_original
     allow(Ability).to receive(:allowed?)
                         .with(user, :read_ai_agents, project)
                         .and_return(read_ai_agents)
-    allow(Ability).to receive(:allowed?)
-                        .with(user, :write_ai_agents, project)
-                        .and_return(write_ai_agents)
 
     sign_in(user)
   end
@@ -39,48 +35,4 @@
       end
     end
   end
-
-  describe 'GET new' do
-    subject(:new_request) do
-      get :new, params: { namespace_id: project.namespace, project_id: project }
-      response
-    end
-
-    it 'renders the template' do
-      expect(new_request).to render_template(:new)
-    end
-
-    context 'when user does not have access' do
-      let(:write_ai_agents) { false }
-
-      it 'renders 404' do
-        expect(new_request).to have_gitlab_http_status(:not_found)
-      end
-    end
-  end
-
-  describe 'GET show' do
-    subject(:show_request) do
-      get :show, params: { namespace_id: project.namespace, project_id: project, agent_id: 1 }
-      response
-    end
-
-    it 'renders the template' do
-      expect(show_request).to render_template(:show)
-    end
-
-    it 'assigns the correct param' do
-      show_request
-
-      expect(assigns[:agent_id]).to eq('1')
-    end
-
-    context 'when user does not have access' do
-      let(:read_ai_agents) { false }
-
-      it 'renders 404' do
-        expect(show_request).to have_gitlab_http_status(:not_found)
-      end
-    end
-  end
 end
diff --git a/ee/spec/features/ai_agents_spec.rb b/ee/spec/features/ai_agents_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..eeeee8d0dc087ebb713f1f65663875df606c7f12
--- /dev/null
+++ b/ee/spec/features/ai_agents_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'AI Agents', :js, feature_category: :mlops do
+  let_it_be(:project) { create(:project) }
+  let_it_be(:user) { create(:user, namespace: project.namespace) }
+  let_it_be(:project_member) { create(:project_member, :reporter, project: project, user: user) }
+
+  before do
+    stub_licensed_features(ai_agents: true)
+    stub_feature_flags(agent_registry: true)
+    sign_in(user)
+  end
+
+  context 'with an authenticated user with reporter permissions' do
+    it 'shows the AI Agents empty state screen when no agents exist' do
+      visit project_ml_agents_path(project)
+      expect(page).to have_content('Create your own AI Agents')
+    end
+
+    it 'shows a list of AI Agents when they exist for a project' do
+      create(:ai_agent, name: "my-agent", project: project)
+
+      visit project_ml_agents_path(project)
+
+      expect(page).to have_content('AI Agents')
+      expect(page).to have_content('my-agent')
+    end
+
+    it 'shows the view screen when clicking on an agent name' do
+      agent1 = create(:ai_agent, name: "my-agent", project: project)
+      create(:ai_agent, name: "my-agent-2", project: project)
+
+      visit project_ml_agents_path(project)
+
+      expect(page).to have_content('AI Agents')
+      expect(page).to have_content('my-agent')
+      expect(page).to have_content('my-agent-2')
+
+      click_on('my-agent')
+
+      expect(page).to have_content("AI Agent: #{agent1.id}")
+    end
+
+    it 'shows the create screen when the button is clicked' do
+      visit project_ml_agents_path(project)
+      expect(page).to have_content('Create your own AI Agents')
+
+      click_on('Create agent')
+
+      expect(page).to have_content('Agent name')
+      expect(page).to have_content('Prompt (optional)')
+    end
+
+    it 'creates an AI agent when the data is supplied and the button clicked' do
+      visit new_project_ml_agent_path(project)
+      expect(page).to have_content('New agent')
+      expect(page).to have_content('Agent name')
+      expect(page).to have_content('Prompt (optional)')
+
+      find('input[data-testid="agent-name"]').set('my-agent-name')
+
+      click_on('Create agent')
+
+      expect(page).to have_content("AI Agent:")
+      expect(page).not_to have_content('New agent')
+      expect(page).not_to have_content('Agent name')
+      expect(page).not_to have_content('Prompt (optional)')
+    end
+  end
+end
diff --git a/ee/spec/frontend/ml/ai_agents/components/agent_list_spec.js b/ee/spec/frontend/ml/ai_agents/components/agent_list_spec.js
index 5139e0dda522ebb0dd0e91a1c20cf6885ed00ede..2fdbe792a8d870eab53b881d7a73cf3cb79e4675 100644
--- a/ee/spec/frontend/ml/ai_agents/components/agent_list_spec.js
+++ b/ee/spec/frontend/ml/ai_agents/components/agent_list_spec.js
@@ -1,4 +1,5 @@
 import { GlTableLite, GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
+import { RouterLinkStub as RouterLink } from '@vue/test-utils';
 import Vue from 'vue';
 import VueApollo from 'vue-apollo';
 import { mountExtended } from 'helpers/vue_test_utils_helper';
@@ -18,6 +19,9 @@ describe('AI Agents List View', () => {
       apolloProvider,
       provide: { projectPath: 'path/to/project' },
       propsData: { createAgentPath: 'path/to/create' },
+      stubs: {
+        RouterLink,
+      },
     });
   };
 
diff --git a/ee/spec/frontend/ml/ai_agents/graphql/mocks.js b/ee/spec/frontend/ml/ai_agents/graphql/mocks.js
index dcfb18692cb5fdec7b47532b1e1c6b40f2f85129..c0b3b2ed04bfb17e517fbe2ba2d3ff8909439b8c 100644
--- a/ee/spec/frontend/ml/ai_agents/graphql/mocks.js
+++ b/ee/spec/frontend/ml/ai_agents/graphql/mocks.js
@@ -4,9 +4,7 @@ export const createAiAgentsResponses = {
       aiAgentCreate: {
         agent: {
           id: 'gid://gitlab/Ai::Agent/1',
-          _links: {
-            showPath: '/some/project/-/ml/agents/1',
-          },
+          routeId: 2,
         },
         errors: [],
       },
@@ -30,6 +28,7 @@ export const listAiAgentsResponses = {
         nodes: [
           {
             id: 'gid://gitlab/Ai::Agent/1',
+            routeId: 2,
             name: 'agent-1',
             versions: [
               {
@@ -38,9 +37,6 @@ export const listAiAgentsResponses = {
                 model: 'default',
               },
             ],
-            _links: {
-              showPath: '/namespace/projects/-/ml/agents/1',
-            },
           },
         ],
         pageInfo: {
diff --git a/ee/spec/frontend/ml/ai_agents/apps/create_agent_spec.js b/ee/spec/frontend/ml/ai_agents/views/create_agent_spec.js
similarity index 86%
rename from ee/spec/frontend/ml/ai_agents/apps/create_agent_spec.js
rename to ee/spec/frontend/ml/ai_agents/views/create_agent_spec.js
index 40830a1172a38eb7c53abadcc2b9d8bfe33e644f..d136903ef2281ff4614b5de6ffc53e1274f5baa3 100644
--- a/ee/spec/frontend/ml/ai_agents/apps/create_agent_spec.js
+++ b/ee/spec/frontend/ml/ai_agents/views/create_agent_spec.js
@@ -8,25 +8,24 @@ import {
 } from '@gitlab/ui';
 import Vue from 'vue';
 import VueApollo from 'vue-apollo';
-import { CreateAgent } from 'ee/ml/ai_agents/apps';
+import CreateAgent from 'ee/ml/ai_agents/views/create_agent.vue';
 import createAiAgentMutation from 'ee/ml/ai_agents/graphql/mutations/create_ai_agent.mutation.graphql';
 import createMockApollo from 'helpers/mock_apollo_helper';
-import { visitUrl } from '~/lib/utils/url_utility';
 import * as Sentry from '~/sentry/sentry_browser_wrapper';
 import waitForPromises from 'helpers/wait_for_promises';
 import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
 import TitleArea from '~/vue_shared/components/registry/title_area.vue';
 import { createAiAgentsResponses } from '../graphql/mocks';
 
-jest.mock('~/lib/utils/url_utility', () => ({
-  ...jest.requireActual('~/lib/utils/url_utility'),
-  visitUrl: jest.fn(),
-}));
-
-describe('ee/ml/ai_agents/apps/create_agent', () => {
+describe('ee/ml/ai_agents/views/create_agent', () => {
   let wrapper;
   let apolloProvider;
 
+  const push = jest.fn();
+  const $router = {
+    push,
+  };
+
   Vue.use(VueApollo);
 
   beforeEach(() => {
@@ -41,7 +40,10 @@ describe('ee/ml/ai_agents/apps/create_agent', () => {
 
     wrapper = shallowMountExtended(CreateAgent, {
       apolloProvider,
-      propsData: { projectPath: 'project/path' },
+      provide: { projectPath: 'project/path' },
+      mocks: {
+        $router,
+      },
     });
   };
 
@@ -99,7 +101,10 @@ describe('ee/ml/ai_agents/apps/create_agent', () => {
 
     await submitForm();
 
-    expect(visitUrl).toHaveBeenCalledWith('/some/project/-/ml/agents/1');
+    expect($router.push).toHaveBeenCalledWith({
+      name: 'show',
+      params: { agentId: 2 },
+    });
   });
 
   it('shows errors when result is a top level error', async () => {
@@ -109,7 +114,7 @@ describe('ee/ml/ai_agents/apps/create_agent', () => {
     await submitForm();
 
     expect(findErrorAlert().text()).toBe('An error has occurred when saving the agent.');
-    expect(visitUrl).not.toHaveBeenCalled();
+    expect(push).not.toHaveBeenCalled();
   });
 
   it('shows errors when result is a validation error', async () => {
@@ -118,6 +123,6 @@ describe('ee/ml/ai_agents/apps/create_agent', () => {
     await submitForm();
 
     expect(findErrorAlert().text()).toBe("Name is invalid, Name can't be blank");
-    expect(visitUrl).not.toHaveBeenCalled();
+    expect(push).not.toHaveBeenCalled();
   });
 });
diff --git a/ee/spec/frontend/ml/ai_agents/apps/list_agents_spec.js b/ee/spec/frontend/ml/ai_agents/views/list_agents_spec.js
similarity index 66%
rename from ee/spec/frontend/ml/ai_agents/apps/list_agents_spec.js
rename to ee/spec/frontend/ml/ai_agents/views/list_agents_spec.js
index dc174aaecbc4b96086e36ec7027bc2e6f39baef1..4bd2f8afa48d8fe42642b29120906f0994caecd1 100644
--- a/ee/spec/frontend/ml/ai_agents/apps/list_agents_spec.js
+++ b/ee/spec/frontend/ml/ai_agents/views/list_agents_spec.js
@@ -1,6 +1,7 @@
-import { GlBadge, GlButton } from '@gitlab/ui';
+import { GlBadge } from '@gitlab/ui';
+import { RouterLinkStub as RouterLink } from '@vue/test-utils';
 import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import { ListAgents } from 'ee/ml/ai_agents/apps';
+import ListAgents from 'ee/ml/ai_agents/views/list_agents.vue';
 import TitleArea from '~/vue_shared/components/registry/title_area.vue';
 import AgentList from 'ee/ml/ai_agents/components/agent_list.vue';
 
@@ -8,16 +9,19 @@ let wrapper;
 
 const createWrapper = () => {
   wrapper = shallowMountExtended(ListAgents, {
-    propsData: { projectPath: 'path/to/project', createAgentPath: 'path/to/create' },
+    provide: { projectPath: 'path/to/project' },
+    stubs: {
+      RouterLink,
+    },
   });
 };
 
 const findTitleArea = () => wrapper.findComponent(TitleArea);
-const findCreateButton = () => findTitleArea().findComponent(GlButton);
+const findCreateButton = () => findTitleArea().findComponent(RouterLink);
 const findBadge = () => wrapper.findComponent(GlBadge);
 const findAgentList = () => wrapper.findComponent(AgentList);
 
-describe('ee/ml/ai_agents/apps/list_agents', () => {
+describe('ee/ml/ai_agents/views/list_agents', () => {
   beforeEach(() => createWrapper());
 
   it('shows the title', () => {
@@ -29,7 +33,9 @@ describe('ee/ml/ai_agents/apps/list_agents', () => {
   });
 
   it('shows create agent button', () => {
-    expect(findCreateButton().attributes().href).toBe('path/to/create');
+    expect(findCreateButton().props('to')).toMatchObject({
+      name: 'create',
+    });
   });
 
   it('shows the agent list', () => {
diff --git a/ee/spec/frontend/ml/ai_agents/apps/show_agent_spec.js b/ee/spec/frontend/ml/ai_agents/views/show_agent_spec.js
similarity index 59%
rename from ee/spec/frontend/ml/ai_agents/apps/show_agent_spec.js
rename to ee/spec/frontend/ml/ai_agents/views/show_agent_spec.js
index ebda18af7f0fa1cfc7768790bb5389c31cb5eed2..fb73d3043363fc08dea10f2e422d56caa44aef6a 100644
--- a/ee/spec/frontend/ml/ai_agents/apps/show_agent_spec.js
+++ b/ee/spec/frontend/ml/ai_agents/views/show_agent_spec.js
@@ -1,20 +1,27 @@
 import { GlExperimentBadge } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import { ShowAgent } from 'ee/ml/ai_agents/apps';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import ShowAgent from 'ee/ml/ai_agents/views/show_agent.vue';
 import TitleArea from '~/vue_shared/components/registry/title_area.vue';
 
 let wrapper;
 
 const createWrapper = () => {
-  wrapper = shallowMount(ShowAgent, {
-    propsData: { projectPath: 'path/to/project', agentId: '2' },
+  wrapper = shallowMountExtended(ShowAgent, {
+    provide: { projectPath: 'path/to/project' },
+    mocks: {
+      $route: {
+        params: {
+          agentId: 2,
+        },
+      },
+    },
   });
 };
 
 const findTitleArea = () => wrapper.findComponent(TitleArea);
 const findBadge = () => wrapper.findComponent(GlExperimentBadge);
 
-describe('ee/ml/ai_agents/apps/create_agent', () => {
+describe('ee/ml/ai_agents/views/create_agent', () => {
   beforeEach(() => createWrapper());
 
   it('shows the title', () => {
diff --git a/ee/spec/graphql/types/ai/agents/agent_links_type_spec.rb b/ee/spec/graphql/types/ai/agents/agent_links_type_spec.rb
deleted file mode 100644
index 8eeb1febc0e31771a6568aaaa390d39d1ab2fd1e..0000000000000000000000000000000000000000
--- a/ee/spec/graphql/types/ai/agents/agent_links_type_spec.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe GitlabSchema.types['AiAgentLinks'], feature_category: :mlops do
-  it 'has the expected fields' do
-    expected_fields = %w[showPath]
-
-    expect(described_class).to include_graphql_fields(*expected_fields)
-  end
-end
diff --git a/ee/spec/graphql/types/ai/agents/agent_type_spec.rb b/ee/spec/graphql/types/ai/agents/agent_type_spec.rb
index 8e5489e6a4a06f2eedc7c145cac2701863e52689..f0c7116cb8078d91a76e0af2dcb7a82cda5cd483 100644
--- a/ee/spec/graphql/types/ai/agents/agent_type_spec.rb
+++ b/ee/spec/graphql/types/ai/agents/agent_type_spec.rb
@@ -4,7 +4,7 @@
 
 RSpec.describe GitlabSchema.types['AiAgent'], feature_category: :mlops do
   it 'has specific fields' do
-    expected_fields = %w[id name created_at versions _links]
+    expected_fields = %w[id name created_at versions]
 
     expect(described_class).to include_graphql_fields(*expected_fields)
   end
diff --git a/ee/spec/presenters/ai/agent_presenter_spec.rb b/ee/spec/presenters/ai/agent_presenter_spec.rb
index a566373d625ae41fc30384458839a28aae7b2513..e91f8df6f374d773509b90c607edc8a4bd4accda 100644
--- a/ee/spec/presenters/ai/agent_presenter_spec.rb
+++ b/ee/spec/presenters/ai/agent_presenter_spec.rb
@@ -6,9 +6,9 @@
   let(:project) { build_stubbed(:project) }
   let(:agent) { build_stubbed(:ai_agent, project: project) }
 
-  describe '#path' do
-    subject { agent.present.path }
+  describe '#route_id' do
+    subject { agent.present.route_id }
 
-    it { is_expected.to eq("/#{project.full_path}/-/ml/agents/#{agent.id}") }
+    it { is_expected.to eq(agent.id) }
   end
 end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index c087347f81527be9164a535bfe0f379e753a31e6..a54584ff1b2b022d324a3816fda6379fcfdd8f8e 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1931,9 +1931,6 @@ msgstr ""
 msgid "AIAgents|Create agent"
 msgstr ""
 
-msgid "AIAgents|New AI Agent"
-msgstr ""
-
 msgid "AIAgents|New agent"
 msgstr ""
 
@@ -4427,12 +4424,6 @@ msgstr ""
 msgid "Agent not found for provided id."
 msgstr ""
 
-msgid "AiAgents|AI Agents"
-msgstr ""
-
-msgid "AiAgents|AI agent"
-msgstr ""
-
 msgid "AiAgents|Agent Name"
 msgstr ""
 
@@ -4442,9 +4433,6 @@ msgstr ""
 msgid "AiAgents|Create your own AI Agents"
 msgstr ""
 
-msgid "AiAgents|Get started"
-msgstr ""
-
 msgid "Akismet"
 msgstr ""