mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
Merge remote-tracking branch 'origin/master' into mergebot/pr1667
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/** Registers the conversation components, shared store, and service callbacks. */
|
||||
import type { Context } from 'cordis'
|
||||
import { deferRegistration, resolveSlotLabel, type BoundActions } from '@deepseek-ai/dsh-client-ui-slots'
|
||||
import { resolveSlotLabel, type BoundActions } from '@deepseek-ai/dsh-client-ui-slots'
|
||||
import type { ISessions, SessionId } from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-layout/client'
|
||||
// Type-only: pulls the locale plugin's Context merge (ctx.locale).
|
||||
@@ -98,20 +98,16 @@ export function apply(ctx: Context): void {
|
||||
const chatStore = createChatStore()
|
||||
const submissionPolicy = new ComposerSubmissionPolicy()
|
||||
|
||||
ctx.effect(() => {
|
||||
const row = deferRegistration(ctx.slots, 'settings.general.item', EnterBehaviorRow, () =>
|
||||
ctx.slots.register({
|
||||
name: 'settings.general.item',
|
||||
id: 'composer-enter',
|
||||
order: 20,
|
||||
locale: NS,
|
||||
inject: (): EnterBehaviorRowInjected => ({
|
||||
hooks: { busyEnter: submissionPolicy.busyEnter },
|
||||
setBusyEnter: (behavior) => { submissionPolicy.setBusyEnter(behavior) },
|
||||
}),
|
||||
}, EnterBehaviorRow))
|
||||
return () => { row.dispose() }
|
||||
}, 'ui-conversation: Enter behavior settings row')
|
||||
ctx.slots.inject('settings.general.item', () => ctx.slots.register({
|
||||
name: 'settings.general.item',
|
||||
id: 'composer-enter',
|
||||
order: 20,
|
||||
locale: NS,
|
||||
inject: (): EnterBehaviorRowInjected => ({
|
||||
hooks: { busyEnter: submissionPolicy.busyEnter },
|
||||
setBusyEnter: (behavior) => { submissionPolicy.setBusyEnter(behavior) },
|
||||
}),
|
||||
}, EnterBehaviorRow))
|
||||
|
||||
// Chat semantic reader positions by session, surviving view switches and
|
||||
// width reflow when the tab ring remounts the view. Deliberately not
|
||||
@@ -338,13 +334,11 @@ export function apply(ctx: Context): void {
|
||||
|
||||
// Class-plugin mount (packages/AGENTS.md service form): the service
|
||||
// registers itself as `conversation` and lives on its own child fiber.
|
||||
// Mounted AFTER the chat entry register above — construction guarantee for
|
||||
// toolview registrants using `inject: ['conversation']` as their load-order
|
||||
// seam: the service being present implies the chat entry (and with it the
|
||||
// 'conversation.chat.toolview' declaration) is on the ledger.
|
||||
// Presentation registrants depend directly on their slot declarations;
|
||||
// this service remains only where conversation actions are required.
|
||||
ctx.plugin(ConversationService, { input: inputHub })
|
||||
|
||||
// The bash sample rides that exact seam, in third-party posture
|
||||
// The bash sample rides the same declaration seam, in third-party posture
|
||||
// (ToolRow-matching Bash · {description} chrome).
|
||||
ctx.plugin(bashToolviewSample)
|
||||
|
||||
|
||||
@@ -213,8 +213,8 @@ export function QueueDock({ useSession, updateQueue, notify, t }: QueueDockProps
|
||||
}
|
||||
|
||||
/**
|
||||
* The dock entry as a plain registrant plugin. The conversation service is the
|
||||
* ordering and action seam; session scopes provide the exact queue owner.
|
||||
* The dock entry as a plain registrant plugin. The conversation service is
|
||||
* the action seam; the slot declaration is its independent lifecycle seam.
|
||||
*/
|
||||
export const queueDockEntry = {
|
||||
name: 'conversation-queue-dock',
|
||||
@@ -224,7 +224,7 @@ export const queueDockEntry = {
|
||||
* @param ctx - registrant context (disposal rides ctx.effect inside slots.register).
|
||||
*/
|
||||
apply(ctx: Context): void {
|
||||
ctx.slots.register({
|
||||
ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({
|
||||
name: 'conversation.input.dock',
|
||||
id: 'queue',
|
||||
order: 20,
|
||||
@@ -239,6 +239,6 @@ export const queueDockEntry = {
|
||||
notify: (level, text) => { conversation.input.for(actx).notify(level, text) },
|
||||
}
|
||||
},
|
||||
}, QueueDock)
|
||||
}, QueueDock))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -137,19 +137,18 @@ export function TodoDock({ useProjection, t }: TodoDockProps) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The plan strip as a plain registrant plugin (QueueDock posture).
|
||||
* `inject: ['conversation']` is the ordering seam: the conversation service
|
||||
* mounts after ui-conversation's slot registrations, so the
|
||||
* 'conversation.input.dock' declaration is on the ledger by then.
|
||||
* The plan strip as a plain registrant plugin (QueueDock posture), following
|
||||
* the input-dock declaration across independent activation and reload.
|
||||
*/
|
||||
export const todoDockEntry = {
|
||||
name: 'conversation-todo-dock',
|
||||
inject: ['slots', 'conversation'],
|
||||
inject: ['slots'],
|
||||
/**
|
||||
* Register the plan strip before the goal and queue entries (order 0).
|
||||
* @param ctx - registrant context (disposal rides ctx.effect inside slots.register).
|
||||
*/
|
||||
apply(ctx: Context): void {
|
||||
ctx.slots.register({ name: 'conversation.input.dock', id: 'todo', order: 0, locale: NS }, TodoDock)
|
||||
ctx.slots.inject('conversation.input.dock', () =>
|
||||
ctx.slots.register({ name: 'conversation.input.dock', id: 'todo', order: 0, locale: NS }, TodoDock))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -83,19 +83,19 @@ export function AskQuestionRow({ toolName, block, inspect, t }: AskQuestionRowPr
|
||||
}
|
||||
|
||||
/**
|
||||
* The ask-question row as a plain registrant plugin, riding the same
|
||||
* load-order seam as todo-toolview: `inject: ['conversation']` guarantees the
|
||||
* chat entry (and with it the 'conversation.chat.toolview' declaration) is on
|
||||
* the ledger.
|
||||
* The ask-question row as a plain registrant plugin following the chat
|
||||
* toolview declaration across independent activation and reload lifetimes.
|
||||
*/
|
||||
export const askQuestionToolview = {
|
||||
name: 'ask-question-toolview',
|
||||
inject: ['slots', 'conversation'],
|
||||
inject: ['slots'],
|
||||
/**
|
||||
* Register the ask-question row into the chat view's keyed toolview hole.
|
||||
* @param ctx - registrant context (disposal rides ctx.effect inside slots.register).
|
||||
*/
|
||||
apply(ctx: Context): void {
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'ask_user_question', locale: NS }, AskQuestionRow)
|
||||
ctx.slots.inject('conversation.chat.toolview', () => ctx.slots.register({
|
||||
name: 'conversation.chat.toolview', key: 'ask_user_question', locale: NS,
|
||||
}, AskQuestionRow))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -166,19 +166,18 @@ export function BashRow({ toolName, block, sessionId, useSessions, inspect, t }:
|
||||
}
|
||||
|
||||
/**
|
||||
* The sample as a plain registrant plugin. `inject` carries the load-order
|
||||
* seam: requiring the conversation service guarantees the chat entry (and
|
||||
* with it the 'conversation.chat.toolview' declaration) is registered —
|
||||
* ui-conversation's apply mounts the service after the chat entry.
|
||||
* The sample as a plain registrant plugin. Slot injection follows the chat
|
||||
* toolview declaration across independent activation and reload lifetimes.
|
||||
*/
|
||||
export const bashToolviewSample = {
|
||||
name: 'bash-toolview-sample',
|
||||
inject: ['slots', 'conversation'],
|
||||
inject: ['slots'],
|
||||
/**
|
||||
* Register the bash row into the chat view's keyed toolview hole.
|
||||
* @param ctx - registrant context (disposal rides ctx.effect inside slots.register).
|
||||
*/
|
||||
apply(ctx: Context): void {
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'bash', locale: NS }, BashRow)
|
||||
ctx.slots.inject('conversation.chat.toolview', () =>
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'bash', locale: NS }, BashRow))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -53,21 +53,21 @@ export function FileMutationRow({ toolName, block, cwd, openFile, inspect, t }:
|
||||
}
|
||||
|
||||
/**
|
||||
* The file-mutation rows as a plain registrant plugin. `inject` carries the
|
||||
* load-order seam: requiring the conversation service guarantees the chat entry
|
||||
* (and with it the 'conversation.chat.toolview' declaration) is registered —
|
||||
* ui-conversation's apply mounts the service after the chat entry.
|
||||
* The file-mutation rows as a plain registrant plugin following the chat
|
||||
* toolview declaration across independent activation and reload lifetimes.
|
||||
*/
|
||||
export const fileMutationToolview = {
|
||||
name: 'file-mutation-toolview',
|
||||
inject: ['slots', 'conversation'],
|
||||
inject: ['slots'],
|
||||
/**
|
||||
* Register the file-mutation row into the chat view's keyed toolview hole
|
||||
* under both mutation tool names.
|
||||
* @param ctx - registrant context (disposal rides ctx.effect inside slots.register).
|
||||
*/
|
||||
apply(ctx: Context): void {
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'edit', locale: NS }, FileMutationRow)
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'write', locale: NS }, FileMutationRow)
|
||||
ctx.slots.inject('conversation.chat.toolview', function* () {
|
||||
yield ctx.slots.register({ name: 'conversation.chat.toolview', key: 'edit', locale: NS }, FileMutationRow)
|
||||
yield ctx.slots.register({ name: 'conversation.chat.toolview', key: 'write', locale: NS }, FileMutationRow)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
@@ -48,19 +48,18 @@ export function ReadRow({ toolName, block, cwd, openFile, inspect, t }: ReadRowP
|
||||
}
|
||||
|
||||
/**
|
||||
* The read row as a plain registrant plugin. `inject` carries the load-order
|
||||
* seam: requiring the conversation service guarantees the chat entry (and with
|
||||
* it the 'conversation.chat.toolview' declaration) is registered —
|
||||
* ui-conversation's apply mounts the service after the chat entry.
|
||||
* The read row as a plain registrant plugin following the chat toolview
|
||||
* declaration across independent activation and reload lifetimes.
|
||||
*/
|
||||
export const readToolview = {
|
||||
name: 'read-toolview',
|
||||
inject: ['slots', 'conversation'],
|
||||
inject: ['slots'],
|
||||
/**
|
||||
* Register the read row into the chat view's keyed toolview hole.
|
||||
* @param ctx - registrant context (disposal rides ctx.effect inside slots.register).
|
||||
*/
|
||||
apply(ctx: Context): void {
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'read', locale: NS }, ReadRow)
|
||||
ctx.slots.inject('conversation.chat.toolview', () =>
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'read', locale: NS }, ReadRow))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -61,22 +61,22 @@ export function SearchRow({ toolName, block, inspect, t }: SearchRowProps) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The search toolview as a plain registrant plugin. `inject` carries the
|
||||
* load-order seam: requiring the conversation service guarantees the chat entry
|
||||
* (and with it the 'conversation.chat.toolview' declaration) is registered.
|
||||
* The one component registers under both keys, since `grep` and `glob` are the
|
||||
* same visual object discriminated only by the result view's `kind`.
|
||||
* The search toolview follows the chat toolview declaration across activation
|
||||
* and reload. One component registers under both keys because `grep` and
|
||||
* `glob` are the same visual object discriminated by the result view's `kind`.
|
||||
*/
|
||||
export const searchToolview = {
|
||||
name: 'search-toolview',
|
||||
inject: ['slots', 'conversation'],
|
||||
inject: ['slots'],
|
||||
/**
|
||||
* Register the search row into the chat view's keyed toolview hole under both
|
||||
* the `grep` and `glob` tool names.
|
||||
* @param ctx - registrant context (disposal rides ctx.effect inside slots.register).
|
||||
*/
|
||||
apply(ctx: Context): void {
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'grep', locale: NS }, SearchRow)
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'glob', locale: NS }, SearchRow)
|
||||
ctx.slots.inject('conversation.chat.toolview', function* () {
|
||||
yield ctx.slots.register({ name: 'conversation.chat.toolview', key: 'grep', locale: NS }, SearchRow)
|
||||
yield ctx.slots.register({ name: 'conversation.chat.toolview', key: 'glob', locale: NS }, SearchRow)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
@@ -71,18 +71,18 @@ export function TodoRow({ toolName, block, inspect, t }: TodoRowProps) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The todo row as a plain registrant plugin, riding the same load-order seam
|
||||
* as the bash sample: `inject: ['conversation']` guarantees the chat entry
|
||||
* (and with it the 'conversation.chat.toolview' declaration) is on the ledger.
|
||||
* The todo row as a plain registrant plugin following the chat toolview
|
||||
* declaration across independent activation and reload lifetimes.
|
||||
*/
|
||||
export const todoToolview = {
|
||||
name: 'todo-toolview',
|
||||
inject: ['slots', 'conversation'],
|
||||
inject: ['slots'],
|
||||
/**
|
||||
* Register the todo row into the chat view's keyed toolview hole.
|
||||
* @param ctx - registrant context (disposal rides ctx.effect inside slots.register).
|
||||
*/
|
||||
apply(ctx: Context): void {
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'todo_write', locale: NS }, TodoRow)
|
||||
ctx.slots.inject('conversation.chat.toolview', () =>
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'todo_write', locale: NS }, TodoRow))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -55,20 +55,20 @@ export function WebRow({ toolName, block, inspect, t }: WebRowProps) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The web rows as a plain registrant plugin, riding the same load-order seam as
|
||||
* the bash sample: `inject: ['conversation']` guarantees the chat entry (and
|
||||
* with it the 'conversation.chat.toolview' declaration) is on the ledger. One
|
||||
* WebRow component registers under both web tool names.
|
||||
* The web rows follow the chat toolview declaration across activation and
|
||||
* reload. One WebRow component registers under both web tool names.
|
||||
*/
|
||||
export const webToolview = {
|
||||
name: 'web-toolview',
|
||||
inject: ['slots', 'conversation'],
|
||||
inject: ['slots'],
|
||||
/**
|
||||
* Register the web row under both web tool names' keyed toolview holes.
|
||||
* @param ctx - registrant context (disposal rides ctx.effect inside slots.register).
|
||||
*/
|
||||
apply(ctx: Context): void {
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'web_search', locale: NS }, WebRow)
|
||||
ctx.slots.register({ name: 'conversation.chat.toolview', key: 'web_fetch', locale: NS }, WebRow)
|
||||
ctx.slots.inject('conversation.chat.toolview', function* () {
|
||||
yield ctx.slots.register({ name: 'conversation.chat.toolview', key: 'web_search', locale: NS }, WebRow)
|
||||
yield ctx.slots.register({ name: 'conversation.chat.toolview', key: 'web_fetch', locale: NS }, WebRow)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user