mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-14 03:30:19 +00:00
🔨 chore(.agents): added skill for agent-signal (#14206)
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
---
|
||||
name: agent-signal
|
||||
description: Build or extend LobeHub Agent Signal pipelines for background or quiet agent work driven by event sources, semantic signals, and action handlers. Use when adding a new Agent Signal source, signal or action type, policy, middleware handler, workflow handoff, dedupe or scope behavior, or observability around `src/server/services/agentSignal/**`, `packages/agent-signal`, or `packages/observability-otel/src/modules/agent-signal`.
|
||||
---
|
||||
|
||||
# Agent Signal
|
||||
|
||||
Use this skill to implement event-driven background work for agents without coupling the work to the foreground chat request.
|
||||
|
||||
Agent Signal has one consistent shape:
|
||||
|
||||
`source event` -> `signal interpretation` -> `action execution` -> built-in result signals
|
||||
|
||||
## Start Here
|
||||
|
||||
1. Read `references/architecture.md` to map the package boundary, runtime queue, scope model, and async workflow handoff.
|
||||
2. Read `references/handlers.md` before writing any new policy, source handler, signal handler, or action handler.
|
||||
3. Read `references/observability.md` when you need tracing, metrics, debugging, or workflow snapshot visibility.
|
||||
|
||||
## Use The Right Entry Point
|
||||
|
||||
- Use `emitAgentSignalSourceEvent(...)` when a server-owned producer should execute the pipeline immediately.
|
||||
- Use `executeAgentSignalSourceEvent(...)` when a worker or controlled backend path already owns execution timing and may inject a runtime guard backend.
|
||||
- Use `enqueueAgentSignalSourceEvent(...)` when the caller should return quickly and let Upstash Workflow process the event out-of-band.
|
||||
- Use `emitAgentSignalSourceEventWithStore(...)` for isolated tests or evals that should avoid ambient Redis state.
|
||||
|
||||
Read:
|
||||
|
||||
- `src/server/services/agentSignal/index.ts`
|
||||
- `src/server/workflows/agentSignal/index.ts`
|
||||
- `src/server/workflows/agentSignal/run.ts`
|
||||
|
||||
## Core Model
|
||||
|
||||
- `source`: A normalized fact that happened. Sources come from producers such as runtime lifecycle events, user messages, or bot ingress.
|
||||
- `signal`: A semantic interpretation derived from one source or from another signal. Signals express meaning, routing, or policy state.
|
||||
- `action`: A concrete side effect planned from one signal. Actions do the work.
|
||||
- `policy`: An installable middleware bundle that registers source, signal, and action handlers.
|
||||
- `procedure`: Not a distinct runtime node. Treat "procedure" as the end-to-end flow for one use case: ingress source, matching handlers, planned actions, execution result, and observability.
|
||||
|
||||
Keep the boundaries strict:
|
||||
|
||||
- Add a new `source` when the outside world produced a new event.
|
||||
- Add a new `signal` when the system needs a reusable semantic interpretation.
|
||||
- Add a new `action` when the runtime needs a concrete side effect.
|
||||
- Add or update a `policy` when you are wiring those pieces together.
|
||||
|
||||
## Implementation Workflow
|
||||
|
||||
1. Decide whether the use case is synchronous or quiet background work.
|
||||
2. Define or reuse a source type in `src/server/services/agentSignal/sourceTypes.ts`.
|
||||
3. Define or reuse signal and action types in `src/server/services/agentSignal/policies/types.ts`.
|
||||
4. Implement handlers with `defineSourceHandler`, `defineSignalHandler`, or `defineActionHandler`.
|
||||
5. Bundle handlers with `defineAgentSignalHandlers(...)`.
|
||||
6. Register the policy in `src/server/services/agentSignal/policies/index.ts` and pass it into the runtime factory if needed.
|
||||
7. Add or update ingress code that emits or enqueues the source event.
|
||||
8. Add observability and tests before considering the flow complete.
|
||||
|
||||
## Default Reading Set
|
||||
|
||||
- Shared semantic core:
|
||||
`packages/agent-signal/src/index.ts`
|
||||
`packages/agent-signal/src/base/builders.ts`
|
||||
`packages/agent-signal/src/base/types.ts`
|
||||
- Server-owned runtime and middleware:
|
||||
`src/server/services/agentSignal/runtime/AgentSignalRuntime.ts`
|
||||
`src/server/services/agentSignal/runtime/AgentSignalScheduler.ts`
|
||||
`src/server/services/agentSignal/runtime/middleware.ts`
|
||||
`src/server/services/agentSignal/runtime/context.ts`
|
||||
- Existing policy example:
|
||||
`src/server/services/agentSignal/policies/analyzeIntent/index.ts`
|
||||
`src/server/services/agentSignal/policies/analyzeIntent/feedbackSatisfaction.ts`
|
||||
`src/server/services/agentSignal/policies/analyzeIntent/feedbackDomain.ts`
|
||||
`src/server/services/agentSignal/policies/analyzeIntent/feedbackAction.ts`
|
||||
`src/server/services/agentSignal/policies/analyzeIntent/actions/userMemory.ts`
|
||||
- Observability:
|
||||
`src/server/services/agentSignal/observability/projector.ts`
|
||||
`src/server/services/agentSignal/observability/traceEvents.ts`
|
||||
`packages/observability-otel/src/modules/agent-signal/index.ts`
|
||||
|
||||
## Implementation Rules
|
||||
|
||||
- Reuse existing source, signal, and action types before adding new ones.
|
||||
- Keep source handlers focused on interpretation and fan-out, not heavy side effects.
|
||||
- Keep action handlers responsible for side effects, idempotency, and executor-style result reporting.
|
||||
- Use stable ids and idempotency keys when the same source can arrive more than once.
|
||||
- Preserve scope discipline. The runtime uses `scopeKey` to serialize related background work.
|
||||
- Prefer the dedicated shared package types and builders from `@lobechat/agent-signal` for normalized nodes and result contracts.
|
||||
- Add focused tests near the touched runtime, policy, or store module. Existing tests under `src/server/services/agentSignal/**/__tests__` are the reference pattern.
|
||||
|
||||
## References
|
||||
|
||||
- Architecture and boundaries: `references/architecture.md`
|
||||
- Writing handlers and policies: `references/handlers.md`
|
||||
- Observability, metrics, and debugging: `references/observability.md`
|
||||
@@ -0,0 +1,4 @@
|
||||
interface:
|
||||
display_name: 'Agent Signal'
|
||||
short_description: 'Build AgentSignal sources, signals, actions, and policies.'
|
||||
default_prompt: 'Use $agent-signal to add a new Agent Signal source, policy, handler, or observability flow.'
|
||||
@@ -0,0 +1,199 @@
|
||||
# Agent Signal Architecture
|
||||
|
||||
## Pipeline
|
||||
|
||||
Use this mental model first:
|
||||
|
||||
```text
|
||||
producer
|
||||
-> emitAgentSignalSourceEvent(...) or enqueueAgentSignalSourceEvent(...)
|
||||
-> emitSourceEvent(...)
|
||||
-> dedupe + scope lock + source normalization
|
||||
-> runtime.emitNormalized(source)
|
||||
-> source handlers
|
||||
-> signal handlers
|
||||
-> action handlers
|
||||
-> built-in result signals
|
||||
-> observability projection + persistence
|
||||
```
|
||||
|
||||
The scheduler is queue-driven, not hard-coded for one policy:
|
||||
|
||||
```text
|
||||
source node
|
||||
-> matching source handlers
|
||||
-> dispatch signals/actions
|
||||
-> matching signal handlers
|
||||
-> dispatch more signals/actions
|
||||
-> matching action handlers
|
||||
-> ExecutorResult
|
||||
-> signal.action.applied | signal.action.skipped | signal.action.failed
|
||||
```
|
||||
|
||||
Read:
|
||||
|
||||
- `src/server/services/agentSignal/index.ts`
|
||||
- `src/server/services/agentSignal/sources/index.ts`
|
||||
- `src/server/services/agentSignal/runtime/AgentSignalScheduler.ts`
|
||||
|
||||
## Package Boundaries
|
||||
|
||||
### `packages/agent-signal`
|
||||
|
||||
Treat this as the shared semantic core.
|
||||
|
||||
It provides:
|
||||
|
||||
- base node types: source, signal, action
|
||||
- builders: `createSource`, `createSignal`, `createAction`
|
||||
- built-in result signal types
|
||||
- runtime result contracts such as `RuntimeProcessorResult` and `ExecutorResult`
|
||||
|
||||
Read:
|
||||
|
||||
- `packages/agent-signal/src/base/types.ts`
|
||||
- `packages/agent-signal/src/base/builders.ts`
|
||||
- `packages/agent-signal/src/types/events.ts`
|
||||
- `packages/agent-signal/src/types/builtin.ts`
|
||||
|
||||
### `src/server/services/agentSignal`
|
||||
|
||||
Treat this as the server-owned implementation layer.
|
||||
|
||||
It owns:
|
||||
|
||||
- source catalogs and payload maps
|
||||
- policy-specific signal and action catalogs
|
||||
- middleware registration
|
||||
- runtime scheduling and guard backends
|
||||
- Redis-backed dedupe, waypoint, and policy state
|
||||
- service entrypoints for synchronous and async execution
|
||||
|
||||
### `packages/observability-otel/src/modules/agent-signal`
|
||||
|
||||
Treat this as shared OTEL ownership for Agent Signal metrics and tracer instances.
|
||||
|
||||
## Core Vocabulary
|
||||
|
||||
### Source
|
||||
|
||||
A source is the normalized external fact that started the chain.
|
||||
|
||||
Examples:
|
||||
|
||||
- `agent.user.message`
|
||||
- `runtime.before_step`
|
||||
- `runtime.after_step`
|
||||
- `client.runtime.start`
|
||||
- `bot.message.merged`
|
||||
|
||||
Define source payloads in:
|
||||
|
||||
- `src/server/services/agentSignal/sourceTypes.ts`
|
||||
|
||||
Build normalized sources in:
|
||||
|
||||
- `src/server/services/agentSignal/sources/buildSource.ts`
|
||||
- `packages/agent-signal/src/base/builders.ts`
|
||||
|
||||
### Signal
|
||||
|
||||
A signal is a semantic interpretation. Signals should be reusable and meaning-oriented.
|
||||
|
||||
Examples from `analyzeIntent`:
|
||||
|
||||
- `signal.feedback.satisfaction`
|
||||
- `signal.feedback.domain.memory`
|
||||
- `signal.feedback.domain.prompt`
|
||||
- `signal.feedback.domain.skill`
|
||||
|
||||
Define server-owned signal types in:
|
||||
|
||||
- `src/server/services/agentSignal/policies/types.ts`
|
||||
|
||||
### Action
|
||||
|
||||
An action is a concrete side effect the runtime should execute.
|
||||
|
||||
Example:
|
||||
|
||||
- `action.user-memory.handle`
|
||||
|
||||
Action handlers usually:
|
||||
|
||||
- check idempotency
|
||||
- call tools, models, or services
|
||||
- return `ExecutorResult`
|
||||
|
||||
### Policy
|
||||
|
||||
A policy is an installable bundle of handlers. It is the composition unit that turns the generic runtime into a feature.
|
||||
|
||||
Example:
|
||||
|
||||
- `createAnalyzeIntentPolicy(...)`
|
||||
|
||||
### Procedure
|
||||
|
||||
"Procedure" is not a first-class type in this runtime. Use the word to describe one end-to-end use case:
|
||||
|
||||
1. define ingress source
|
||||
2. emit or enqueue the source
|
||||
3. interpret source into signals
|
||||
4. plan actions from signals
|
||||
5. execute actions
|
||||
6. persist trace and metrics
|
||||
|
||||
When a user asks for "the procedure", document the flow above and point to the exact producer, handlers, and execution entrypoint.
|
||||
|
||||
## Scope, Deduping, And Quiet Background Work
|
||||
|
||||
`scopeKey` is the serialization boundary for related work. It is used for:
|
||||
|
||||
- source dedupe windows
|
||||
- scope locks during source generation
|
||||
- runtime guard state
|
||||
- waypoint persistence for queued processing
|
||||
|
||||
Read:
|
||||
|
||||
- `src/server/services/agentSignal/sources/index.ts`
|
||||
- `src/server/services/agentSignal/runtime/context.ts`
|
||||
- `src/server/services/agentSignal/constants.ts`
|
||||
|
||||
Use `enqueueAgentSignalSourceEvent(...)` when the work should stay quiet and out-of-band. That path:
|
||||
|
||||
1. normalizes the source envelope
|
||||
2. derives or reuses `scopeKey`
|
||||
3. triggers `AgentSignalWorkflow`
|
||||
4. executes later in `runAgentSignalWorkflow`
|
||||
|
||||
This is the preferred path when the UI request should finish immediately and the policy can run in the background.
|
||||
|
||||
Read:
|
||||
|
||||
- `src/server/workflows/agentSignal/index.ts`
|
||||
- `src/server/workflows/agentSignal/run.ts`
|
||||
|
||||
## Existing Example: `analyzeIntent`
|
||||
|
||||
Use `analyzeIntent` as the reference chain:
|
||||
|
||||
```text
|
||||
agent.user.message
|
||||
-> feedback satisfaction source handler
|
||||
-> signal.feedback.satisfaction
|
||||
-> feedback domain signal handler
|
||||
-> signal.feedback.domain.*
|
||||
-> feedback action planner
|
||||
-> action.user-memory.handle
|
||||
-> signal.action.applied | skipped | failed
|
||||
```
|
||||
|
||||
Read:
|
||||
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/index.ts`
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/feedbackSatisfaction.ts`
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/feedbackDomain.ts`
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/feedbackAction.ts`
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/actions/userMemory.ts`
|
||||
@@ -0,0 +1,228 @@
|
||||
# Writing Handlers And Policies
|
||||
|
||||
## Fluent Registration API
|
||||
|
||||
Use the middleware helpers in `src/server/services/agentSignal/runtime/middleware.ts`.
|
||||
|
||||
They provide:
|
||||
|
||||
- `defineSourceHandler(...)`
|
||||
- `defineSignalHandler(...)`
|
||||
- `defineActionHandler(...)`
|
||||
- `defineAgentSignalHandlers(...)`
|
||||
|
||||
These helpers do two jobs:
|
||||
|
||||
1. keep handler registration terse
|
||||
2. preserve strong typing when `listen` points at concrete source, signal, or action types
|
||||
|
||||
## Handler Shape
|
||||
|
||||
Each handler receives:
|
||||
|
||||
- the current runtime node
|
||||
- `RuntimeProcessorContext`
|
||||
|
||||
The context gives you:
|
||||
|
||||
- `scopeKey`
|
||||
- `now()`
|
||||
- `runtimeState.getGuardState(lane)`
|
||||
- `runtimeState.touchGuardState(lane, now?)`
|
||||
|
||||
Read:
|
||||
|
||||
- `src/server/services/agentSignal/runtime/context.ts`
|
||||
|
||||
## Return Contracts
|
||||
|
||||
Return one of these shapes:
|
||||
|
||||
- `void`: no fan-out, stop at this handler
|
||||
- `{ status: 'dispatch', signals?, actions? }`: continue the chain
|
||||
- `{ status: 'wait', pending? }`: pause for later host coordination
|
||||
- `{ status: 'schedule', nextHop }`: schedule another hop
|
||||
- `{ status: 'conclude', concluded? }`: stop with a terminal runtime result
|
||||
- `ExecutorResult`: only for action handlers that performed a concrete side effect
|
||||
|
||||
Read:
|
||||
|
||||
- `packages/agent-signal/src/base/types.ts`
|
||||
- `src/server/services/agentSignal/runtime/AgentSignalScheduler.ts`
|
||||
|
||||
## Policy Composition Pattern
|
||||
|
||||
Use `defineAgentSignalHandlers([...])` to bundle related handlers into one policy.
|
||||
|
||||
Example from `analyzeIntent`:
|
||||
|
||||
```ts
|
||||
return defineAgentSignalHandlers([
|
||||
createFeedbackSatisfactionJudgeProcessor(...),
|
||||
createFeedbackDomainJudgeSignalHandler(...),
|
||||
createFeedbackActionPlannerSignalHandler(),
|
||||
defineUserMemoryActionHandler(...),
|
||||
]);
|
||||
```
|
||||
|
||||
That bundle is later passed into the runtime via:
|
||||
|
||||
- `createDefaultAgentSignalPolicies(...)`
|
||||
- `createAgentSignalRuntime({ policies })`
|
||||
|
||||
Read:
|
||||
|
||||
- `src/server/services/agentSignal/policies/index.ts`
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/index.ts`
|
||||
|
||||
## Source Handler Pattern
|
||||
|
||||
Use a source handler when you are interpreting a producer event into semantic signals.
|
||||
|
||||
Reference:
|
||||
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/feedbackSatisfaction.ts`
|
||||
|
||||
Pattern:
|
||||
|
||||
```ts
|
||||
return defineSourceHandler(
|
||||
AGENT_SIGNAL_SOURCE_TYPES.agentUserMessage,
|
||||
'agent.user.message:my-handler',
|
||||
async (source, ctx): Promise<RuntimeProcessorResult | void> => {
|
||||
// interpret source payload
|
||||
// optionally use ctx.runtimeState
|
||||
|
||||
return {
|
||||
signals: [
|
||||
/* one or more semantic signals */
|
||||
],
|
||||
status: 'dispatch',
|
||||
};
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
Write source handlers when:
|
||||
|
||||
- a raw message, lifecycle event, or bot ingress needs interpretation
|
||||
- the work is still semantic, not side-effectful
|
||||
|
||||
## Signal Handler Pattern
|
||||
|
||||
Use a signal handler when one semantic state should branch into more semantic states or planned actions.
|
||||
|
||||
References:
|
||||
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/feedbackDomain.ts`
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/feedbackAction.ts`
|
||||
|
||||
Pattern:
|
||||
|
||||
```ts
|
||||
return defineSignalHandler(
|
||||
MY_SIGNAL_TYPE,
|
||||
'signal.my-policy-router',
|
||||
async (signal): Promise<RuntimeProcessorResult | void> => {
|
||||
return {
|
||||
actions: [
|
||||
/* planned work */
|
||||
],
|
||||
status: 'dispatch',
|
||||
};
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
Use signal handlers for:
|
||||
|
||||
- routing
|
||||
- fan-out
|
||||
- filtering
|
||||
- conflict resolution
|
||||
- converting interpretation into planned actions
|
||||
|
||||
## Action Handler Pattern
|
||||
|
||||
Use an action handler when the runtime should do actual work.
|
||||
|
||||
Reference:
|
||||
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/actions/userMemory.ts`
|
||||
|
||||
Pattern:
|
||||
|
||||
```ts
|
||||
return defineActionHandler(
|
||||
MY_ACTION_TYPE,
|
||||
'action.my-policy-executor',
|
||||
async (action, ctx): Promise<ExecutorResult> => {
|
||||
// run service/tool/model side effect
|
||||
// check idempotency if needed
|
||||
|
||||
return {
|
||||
actionId: action.actionId,
|
||||
attempt: {
|
||||
completedAt: ctx.now(),
|
||||
current: 1,
|
||||
startedAt,
|
||||
status: 'succeeded',
|
||||
},
|
||||
status: 'applied',
|
||||
};
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
Keep these rules:
|
||||
|
||||
- perform idempotency checks here or immediately before side effects
|
||||
- return stable `actionId`
|
||||
- include failure detail in `error`
|
||||
- let the scheduler turn the `ExecutorResult` into built-in result signals
|
||||
|
||||
## Source, Signal, And Action Type Placement
|
||||
|
||||
Use this split:
|
||||
|
||||
- external event payloads:
|
||||
`src/server/services/agentSignal/sourceTypes.ts`
|
||||
- policy-owned signal and action payloads:
|
||||
`src/server/services/agentSignal/policies/types.ts`
|
||||
- normalized shared node contracts:
|
||||
`packages/agent-signal/src/base/types.ts`
|
||||
|
||||
Do not put app-specific signal catalogs into `packages/agent-signal`. That package should stay generic and reusable.
|
||||
|
||||
## Choosing The Right Node
|
||||
|
||||
Choose `source` when:
|
||||
|
||||
- the outside world emitted a new fact
|
||||
|
||||
Choose `signal` when:
|
||||
|
||||
- the system needs semantic meaning that downstream handlers can reuse
|
||||
|
||||
Choose `action` when:
|
||||
|
||||
- the runtime is ready for a concrete side effect
|
||||
|
||||
If a handler both interprets meaning and performs side effects, split it. That keeps chains inspectable and testable.
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
Prefer focused tests near the touched code.
|
||||
|
||||
Useful references:
|
||||
|
||||
- `src/server/services/agentSignal/runtime/__tests__/AgentSignalRuntime.test.ts`
|
||||
- `src/server/services/agentSignal/__tests__/index.integration.test.ts`
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/__tests__/*`
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/actions/__tests__/*`
|
||||
|
||||
Test at the smallest level that proves the behavior:
|
||||
|
||||
- handler unit test for one routing rule
|
||||
- runtime test for queue fan-out
|
||||
- integration test for service ingress and observability persistence
|
||||
@@ -0,0 +1,118 @@
|
||||
# Observability And Debugging
|
||||
|
||||
## OTEL Ownership
|
||||
|
||||
Use `packages/observability-otel/src/modules/agent-signal/index.ts` for the shared tracer and metrics.
|
||||
|
||||
Available instruments:
|
||||
|
||||
- `tracer`
|
||||
- `sourceCounter`
|
||||
- `signalCounter`
|
||||
- `actionCounter`
|
||||
- `actionResultCounter`
|
||||
- `chainCounter`
|
||||
- `signalActionTransitionCounter`
|
||||
- `chainDurationHistogram`
|
||||
- `actionDurationHistogram`
|
||||
|
||||
Use this module when you need shared telemetry ownership instead of creating feature-local meters or tracers.
|
||||
|
||||
## Projection Pipeline
|
||||
|
||||
After runtime execution, the service projects one compact observability model from the full chain.
|
||||
|
||||
Read:
|
||||
|
||||
- `src/server/services/agentSignal/observability/projector.ts`
|
||||
- `src/server/services/agentSignal/observability/traceEvents.ts`
|
||||
- `src/server/services/agentSignal/observability/store.ts`
|
||||
|
||||
Projection outputs:
|
||||
|
||||
- a trace envelope with source, signals, actions, results, edges, and handler runs
|
||||
- a compact telemetry record with dominant path, status breakdown, and chain metadata
|
||||
|
||||
This projection is built from:
|
||||
|
||||
- source node
|
||||
- emitted signals
|
||||
- planned actions
|
||||
- executor results
|
||||
|
||||
## How To Inspect A Chain
|
||||
|
||||
Use this order:
|
||||
|
||||
1. Inspect the source type and payload.
|
||||
2. Inspect emitted signals.
|
||||
3. Inspect planned actions.
|
||||
4. Inspect executor results.
|
||||
5. Inspect projected edges and dominant path.
|
||||
|
||||
The helper `toAgentSignalTraceEvents(...)` flattens a chain into compact event records suitable for tracing snapshots.
|
||||
|
||||
## Workflow Snapshot Bridge
|
||||
|
||||
Workflow-triggered runs do not naturally pass through the normal foreground runtime snapshot path, so `runAgentSignalWorkflow` adds a development-only bridge into `.agent-tracing/`.
|
||||
|
||||
Read:
|
||||
|
||||
- `src/server/workflows/agentSignal/run.ts`
|
||||
|
||||
Use that path when:
|
||||
|
||||
- the source was enqueued with `enqueueAgentSignalSourceEvent(...)`
|
||||
- you need local trace visibility for quiet background work
|
||||
|
||||
## Common Debug Questions
|
||||
|
||||
### The source emits but nothing happens
|
||||
|
||||
Check:
|
||||
|
||||
- feature gate enabled for the user
|
||||
- source type matches a registered source handler
|
||||
- dedupe or scope lock did not short-circuit generation
|
||||
|
||||
Read:
|
||||
|
||||
- `src/server/services/agentSignal/index.ts`
|
||||
- `src/server/services/agentSignal/sources/index.ts`
|
||||
|
||||
### The signal exists but no action runs
|
||||
|
||||
Check:
|
||||
|
||||
- the signal type has a registered signal handler
|
||||
- the signal handler returns `status: 'dispatch'`
|
||||
- the handler actually returned actions
|
||||
|
||||
### The action runs twice
|
||||
|
||||
Check:
|
||||
|
||||
- source dedupe key stability
|
||||
- action idempotency strategy
|
||||
- scope key stability across retries and workflow handoff
|
||||
|
||||
Reference:
|
||||
|
||||
- `src/server/services/agentSignal/policies/actionIdempotency.ts`
|
||||
- `src/server/services/agentSignal/policies/analyzeIntent/actions/userMemory.ts`
|
||||
|
||||
### Background runs are hard to discover
|
||||
|
||||
Check:
|
||||
|
||||
- workflow snapshot bridge in development
|
||||
- projected telemetry record contents
|
||||
- OTEL counters and histograms in the shared module
|
||||
|
||||
## Minimal Completion Checklist
|
||||
|
||||
- source ingress is testable
|
||||
- handler registration is discoverable from the policy factory
|
||||
- action executor returns structured results
|
||||
- projection includes the new path cleanly
|
||||
- tests cover at least one happy path and one no-op or failure path
|
||||
Reference in New Issue
Block a user