Dropstone CLI

Dropstone SDK

Dropstone agent runtime-க்கான type-safe JS கிளையண்ட். SDK அமர்வுகள் Dropstone-இன் cross-surface நினைவகத்தை (Continuity) பெறுகின்றன — CLI, chat, மற்றும் SDK உடன் பகிரப்பட்ட ஒரு நிலையான நினைவகம்.

Dropstone JS/TS SDK ஆனது Dropstone agent runtime-உடன் தொடர்புகொள்வதற்கான type-safe கிளையண்ட்டை வழங்குகிறது. இது dropstone serve-ஐ ஒரு subprocess ஆக இயக்கி, அதை நோக்கி ஒரு typed HTTP கிளையண்ட்டை உங்களுக்கு வழங்குகிறது. CLI பயன்படுத்தும் அதே உள்ளூர் agent-ஐ இது இயக்குவதால், ஒவ்வொரு SDK அமர்வும் உங்கள் கணக்கு நினைவகத்தைப் பெறுகிறது — CLI, chat, அல்லது SDK-இல் ஒருமுறை கற்றுக்கொடுத்தால் ஒவ்வொரு மேற்பரப்பும் அதை ஏற்கனவே அறிந்திருக்கும் (பார்க்க Memory (Continuity)).

CI-இல் headless API அணுகல் தேவையா?

முற்றிலும் programmatic பயன்பாட்டிற்கு (CI pipelines, automation, serverless), DROPSTONE_API_KEY உடன் HTTP API-ஐ விரும்புங்கள். இந்தப் பக்கத்தில் உள்ள SDK ஆனது, CLI binary அருகில் நிறுவப்பட்டுள்ள Node செயல்பாட்டில் interactive agent-ஐ உட்பொதிப்பதற்கானது.

அடிப்படை HTTP API எவ்வாறு செயல்படுகிறது என்பதற்கு Server பக்கத்தைப் பார்க்கவும்.


நிறுவல்

npm-இலிருந்து SDK-ஐ நிறுவவும்:

npm install @blankline/dropstone-sdk

Headless API கிளையண்ட்

CI pipelines, automation, மற்றும் serverless-க்கு உங்களுக்கு CLI தேவையில்லை. API key உடன் Dropstone HTTP API-யுடன் நேரடியாகப் பேசும் headless கிளையண்ட்டைப் பயன்படுத்தவும்:

import { createDropstoneApi } from "@blankline/dropstone-sdk"

// சூழலில் இருந்து DROPSTONE_API_KEY-ஐ தானாகவே படிக்கிறது.
const dropstone = createDropstoneApi()

const resp = await dropstone.chat.completions.create({
  model: "dropstone-fast", // அல்லது "dropstone-pro" / "dropstone-heavy"
  messages: [{ role: "user", content: "Debugging பற்றி ஒரு haiku எழுது." }],
})

console.log(resp.choices[0].message.content)
console.log("Cost: $" + resp.usage?.cost) // வசூலிக்கப்பட்ட தொகை, USD-இல்

API key பெறுதல்

  1. dropstone.io/dashboard-இல் உள்நுழையவும்.
  2. dropstone.io/dashboard/settings-இல் Settings → API-ஐத் திறந்து ஒரு key-ஐ உருவாக்கவும் — இது dsk_live_<43 chars> போல் இருக்கும்.
  3. அதை ஒரு environment variable ஆக அமைக்கவும் (அல்லது createDropstoneApi-க்கு apiKey-ஐ அனுப்பவும்):
export DROPSTONE_API_KEY=dsk_live_...

Note

உங்கள் API key-ஐ கடவுச்சொல் போல் கருதுங்கள். அதை git-இல் commit செய்யவோ அல்லது frontend bundle-இல் உட்பொதிக்கவோ வேண்டாம். API-key கோரிக்கைகள் உங்கள் prepaid credit இருப்பிலிருந்து pay-per-use அடிப்படையில் வசூலிக்கப்படுகின்றன — plan கொடுப்பனவுகள் பொருந்தாது. பார்க்க Usage & limits.

Streaming அதே வழியில் செயல்படுகிறது, மேலும் கிளையண்ட் OpenAI-க்கு இணக்கமானது — OpenAI SDK-ஐ Dropstone-இன் base URL-க்கு சுட்டிக்காட்டலாம்:

const stream = await dropstone.chat.completions.create({
  model: "dropstone-fast",
  stream: true,
  messages: [{ role: "user", content: "5 வரை எண்ணு." }],
})

for await (const chunk of stream) {
  process.stdout.write(chunk.choices?.[0]?.delta?.content ?? "")
}

முழு குறிப்புக்கு HTTP API பக்கத்தைப் பார்க்கவும்.


கிளையண்ட் உருவாக்கம்

dropstone-இன் ஒரு நிகழ்வை உருவாக்கவும்:

import { createDropstone } from "@blankline/dropstone-sdk"

const { client } = await createDropstone()

இது ஒரு server மற்றும் ஒரு client இரண்டையும் தொடங்குகிறது. ஒவ்வொரு SDK முறையும் { data, request, response }-ஐ திருப்பித் தருகிறது, எனவே payload-ஐ .data வழியாக அணுகவும்.

இயல்பாக, server அந்த இயந்திரத்தில் dropstone auth login யார் இயக்கினாரோ அவராக உள்நுழைகிறது. கவனிக்கப்படாத host-இல் அத்தகைய கணக்கு இல்லை, எனவே config வழியாக API key மற்றும் வெளிப்படையான permission allowlist-ஐ அனுப்பவும்:

const { client } = await createDropstone({
  config: {
    provider: {
      dropstone: {
        options: {
          apiKey: process.env.DROPSTONE_API_KEY,
          baseURL: "https://api.dropstone.io/api/v1",
        },
      },
    },
    permission: { "*": "deny", read: "allow", edit: "allow", glob: "allow", grep: "allow", bash: "allow" },
  },
})

இரண்டு பகுதிகளும் தேவை. API keys /v1-இல் நிராகரிக்கப்படுகின்றன, மேலும் இயல்பான build agent ஒவ்வொரு tool அழைப்புக்கு முன்பும் கேட்கிறது, எனவே allowlist இல்லாமல் இயக்கம் யாரும் கொடுக்க முடியாத ஒப்புதலுக்காகக் காத்திருந்து, தோல்வியடைவதற்குப் பதிலாகத் தொங்குகிறது. Prompt-இல் "agent": "accept all" அனுப்புவது allowlist-க்கு மாற்றாகும். பார்க்க Server மற்றும் Permissions.

விருப்பங்கள்

OptionTypeDescriptionDefault
hostnamestringServer hostname127.0.0.1
portnumberServer port4096
signalAbortSignalரத்துசெய்வதற்கான Abort signalundefined
timeoutnumberServer தொடக்கத்திற்கான ms-இல் timeout5000
configConfigகட்டமைப்பு பொருள்{}

கட்டமைப்பு

நடத்தையைத் தனிப்பயனாக்க ஒரு கட்டமைப்பு பொருளை அனுப்பலாம். நிகழ்வு உங்கள் dropstone.json-ஐ இன்னும் எடுக்கிறது, ஆனால் நீங்கள் கட்டமைப்பை inline ஆக மேலெழுதலாம் அல்லது சேர்க்கலாம்:

import { createDropstone } from "@blankline/dropstone-sdk"

const dropstone = await createDropstone({
  hostname: "127.0.0.1",
  port: 4096,
  config: {
    model: "dropstone/dropstone-pro",
  },
})

console.log(`Server running at ${dropstone.server.url}`)

dropstone.server.close()

Memory (Continuity)

Dropstone ஒவ்வொரு கணக்கிற்கும் ஒரு நிலையான நினைவகத்தை வைத்திருக்கிறது. அதை நாங்கள் Continuity என்று அழைக்கிறோம் — CLI, chat, VS Code, மற்றும் SDK ஆகியவற்றால் பகிரப்பட்ட cross-surface நினைவகம். எங்கும் ஒருமுறை கற்றுக்கொடுத்தால் ஒவ்வொரு மேற்பரப்பும் அதை ஏற்கனவே அறிந்திருக்கும்.

SDK வழியாக நீங்கள் இயக்கும் அமர்வுகள் CLI போன்ற அதே கணக்கு நினைவகத்தைப் பயன்படுத்துகின்றன. CLI-க்கு நீங்கள் கற்றுக்கொடுப்பது SDK அமர்வுகளுக்கு ஏற்கனவே தெரியும், மேலும் ஒரு SDK அமர்வு பதிவுசெய்வது CLI மற்றும் chat-இல் மீண்டும் கிடைக்கும். ஒவ்வொரு முறையும், agent பதிலளிக்கும் முன் தொடர்புடைய நினைவகத்தை தானாகவே நினைவுபடுத்துகிறது, எனவே அது ஏற்கனவே தெரிந்ததை மீண்டும் கற்காது.

SDK agent நினைவகத்தை நேரடியாகப் படிக்கவும் எழுதவும் முடியும், CLI போன்ற அதே கருவிகளுடன்:

Toolநோக்கம்
memory_recallதற்போதைய பணிக்கான மிகவும் பொருத்தமான பாடங்களை நினைவுபடுத்து
record_lessonநீடித்த பாடத்தைச் சேமி (ஒரு விதி அல்லது ஒரு உண்மை)
edit_lessonசேமிக்கப்பட்ட பாடம் காலாவதியானதாக அல்லது மோசமாக வார்த்தைகளில் இருந்தால் அதை மீண்டும் எழுது
list_lessonsஉங்களைப் பற்றி அது கற்றுக்கொண்ட அனைத்தையும் காட்டு
forget_lessonஒரு பாடத்தை அகற்று

Note

Memory-க்கு Dropstone-இல் உள்நுழைந்திருக்க வேண்டும். SDK server CLI போன்ற அதே auth.json-ஐப் படிக்கிறது, எனவே dropstone உடன் ஒருமுறை உள்நுழைந்தால் SDK அமர்வுகள் அதே கணக்கு நினைவகத்தைப் பெறுகின்றன. நீங்கள் உள்நுழையவில்லை என்றால் எதுவும் சேமிக்கப்படாது.

எடுத்துக்காட்டு

குறியீட்டிலிருந்து ஒரு விருப்பத்தைக் கூறுங்கள், அது CLI-இல் பதிவுசெய்யப்படும் அதே வழியில் பதிவுசெய்யப்படுகிறது — பின்னர் CLI மற்றும் chat-இல் தெரியும்:

const { client } = await createDropstone()

const session = await client.session.create({ body: { title: "Teach memory" } })

await client.session.prompt({
  path: { id: session.data.id },
  body: {
    parts: [{ type: "text", text: "இதை ஒரு நிலையான விதியாக நினைவில் வை: எப்போதும் bun-ஐ பயன்படுத்து, npm-ஐ அல்ல." }],
  },
})

Continuity vs AGENTS.md

AGENTS.md என்பது குழு மரபுகளுக்காக நீங்கள் Git-இல் commit செய்யும் ஒரு திட்ட கோப்பு — நிலையானது, repo-க்கு வரம்பிடப்பட்டது, மேலும் அதை clone செய்யும் எவருடனும் பகிரப்படுகிறது. Continuity உங்கள் தனிப்பட்ட கணக்கு நினைவகம்: CLI, chat, அல்லது SDK-இல் நீங்கள் கற்றுக்கொடுப்பது உங்கள் கணக்கை மேற்பரப்புகள் மற்றும் திட்டங்களுக்கு இடையே பின்தொடர்கிறது. அவை வெவ்வேறு சிக்கல்களைத் தீர்க்கின்றன மற்றும் சிறப்பாக ஒன்றாக வேலை செய்கின்றன — AGENTS.md-இல் திட்ட விதிகள், Continuity-இல் தனிப்பட்ட cross-surface நினைவகம். பார்க்க Rules மற்றும் Memory.

என்ன நினைவில் வைக்கப்படுகிறது

Memory நீங்கள் வெளிப்படையாகக் கற்றுக்கொடுக்கும் விதிகள் மற்றும் உண்மைகளை மட்டுமே சேமிக்கிறது — அமர்வுகளுக்கு இடையே எடுத்துச் செல்லத் தகுந்த விருப்பங்கள், மரபுகள், மற்றும் திருத்தங்கள். இது ஒரு ஒற்றை அமர்வின் நிலையற்ற சூழலில் இருந்து வேறுபட்டது, இது அமர்வு முடிந்த பிறகு வைக்கப்படாது.

Dropstone எதை வைத்திருக்க வேண்டும் என்பதை எவ்வாறு முடிவு செய்கிறது என்பதற்கு Memory பக்கத்தைப் பார்க்கவும்.


Client மட்டும்

உங்களிடம் ஏற்கனவே இயங்கும் dropstone நிகழ்வு இருந்தால், அதனுடன் இணைக்க ஒரு client நிகழ்வை உருவாக்கலாம்:

import { createDropstoneClient } from "@blankline/dropstone-sdk"

const client = createDropstoneClient({
  baseUrl: "http://localhost:4096",
})

விருப்பங்கள்

OptionTypeDescriptionDefault
baseUrlstringServer-இன் URLhttp://localhost:4096
fetchfunctionதனிப்பயன் fetch செயலாக்கம்globalThis.fetch
parseAsstringபதில் பாக்கும் முறைauto
responseStylestringதிரும்பும் பாணி: data அல்லது fieldsfields
throwOnErrorbooleanதிரும்புவதற்குப் பதிலாக பிழைகளை எறிfalse

வகைகள்

SDK அனைத்து API வகைகளுக்கான TypeScript வரையறைகளை உள்ளடக்கியது. அவற்றை நேரடியாக இறக்குமதி செய்யவும்:

import type { Session, Message, Part } from "@blankline/dropstone-sdk"

அனைத்து வகைகளும் server-இன் OpenAPI விவரக்குறிப்பிலிருந்து உருவாக்கப்படுகின்றன, எனவே TypeScript-இல் நீங்கள் காணும் பெயர்கள் server கோரிக்கை மற்றும் பதில் வடிவங்களுடன் ஒன்றுக்கொன்று ஒத்துப்போகின்றன.


பிழைகள்

SDK நீங்கள் பிடித்து கையாளக்கூடிய பிழைகளை எறியலாம்:

try {
  await client.session.get({ path: { id: "invalid-id" } })
} catch (error) {
  console.error("Failed to get session:", (error as Error).message)
}

கட்டமைக்கப்பட்ட வெளியீடு

JSON schema கொண்ட format-ஐக் குறிப்பிடுவதன் மூலம் மாதிரியிலிருந்து கட்டமைக்கப்பட்ட JSON வெளியீட்டைக் கோரலாம். மாதிரி உங்கள் schema-உடன் பொருந்தும் சரிபார்க்கப்பட்ட JSON-ஐத் திருப்பித் தர StructuredOutput கருவியைப் பயன்படுத்தும்.

அடிப்படை பயன்பாடு

const result = await client.session.prompt({
  path: { id: sessionId },
  body: {
    parts: [{ type: "text", text: "Dropstone-ஐ ஆராய்ந்து நிறுவன தகவலை வழங்கு" }],
    format: {
      type: "json_schema",
      schema: {
        type: "object",
        properties: {
          company: { type: "string", description: "நிறுவன பெயர்" },
          founded: { type: "number", description: "நிறுவப்பட்ட ஆண்டு" },
          products: {
            type: "array",
            items: { type: "string" },
            description: "முக்கிய தயாரிப்புகள்",
          },
        },
        required: ["company", "founded"],
      },
    },
  },
})

// கட்டமைக்கப்பட்ட வெளியீட்டை அணுகவும்
console.log(result.data.info.structured_output)
// { company: "Dropstone", founded: 2024, products: ["Dropstone CLI"] }

வெளியீட்டு வடிவ வகைகள்

TypeDescription
textஇயல்பு. நிலையான உரை பதில் (கட்டமைக்கப்பட்ட வெளியீடு இல்லை)
json_schemaவழங்கப்பட்ட schema-உடன் பொருந்தும் சரிபார்க்கப்பட்ட JSON-ஐ திருப்பித் தருகிறது

JSON Schema வடிவம்

type: 'json_schema' பயன்படுத்தும்போது, வழங்கவும்:

FieldTypeDescription
type'json_schema'தேவை. JSON schema முறையைக் குறிப்பிடுகிறது
schemaobjectதேவை. வெளியீட்டு கட்டமைப்பை வரையறுக்கும் JSON Schema பொருள்
retryCountnumberவிருப்பம். சரிபார்ப்பு மறுமுயற்சிகளின் எண்ணிக்கை (இயல்பு: 2)

பிழை கையாளுதல்

அனைத்து மறுமுயற்சிகளுக்குப் பிறகும் மாதிரி சரியான கட்டமைக்கப்பட்ட வெளியீட்டை உருவாக்கத் தவறினால், பதிலில் StructuredOutputError சேர்க்கப்படும்:

if (result.data.info.error?.name === "StructuredOutputError") {
  console.error("Failed to produce structured output:", result.data.info.error.message)
  console.error("Attempts:", result.data.info.error.retries)
}

சிறந்த நடைமுறைகள்

  1. உங்கள் schema பண்புகளில் தெளிவான விளக்கங்களை வழங்கவும் — எந்த தரவைப் பிரித்தெடுக்க வேண்டும் என்பதை மாதிரி புரிந்துகொள்ள உதவும்
  2. required-ஐ பயன்படுத்தவும் — எந்த புலங்கள் இருக்க வேண்டும் என்பதைக் குறிப்பிட
  3. Schemas-ஐ கவனம் செலுத்தி வைக்கவும் — சிக்கலான nested schemas மாதிரி சரியாக நிரப்புவது கடினமாக இருக்கலாம்
  4. பொருத்தமான retryCount-ஐ அமைக்கவும் — சிக்கலான schemas-க்கு அதிகரிக்கவும், எளியவற்றுக்கு குறைக்கவும்

APIs

SDK அனைத்து server API-களையும் type-safe கிளையண்ட் மூலம் வெளிப்படுத்துகிறது.


Global

MethodDescriptionResponse
global.health()Server ஆரோக்கியம் மற்றும் பதிப்பைச் சரிபார்{ healthy: true, version: string }

எடுத்துக்காட்டுகள்

const health = await client.global.health()
console.log(health.data.version)

App

MethodDescriptionResponse
app.log()ஒரு log பதிவை எழுதுboolean
app.agents()கிடைக்கக்கூடிய அனைத்து agents-ஐ பட்டியலிடுAgent[]

எடுத்துக்காட்டுகள்

// ஒரு log பதிவை எழுது
await client.app.log({
  body: {
    service: "my-app",
    level: "info",
    message: "Operation completed",
  },
})

// கிடைக்கக்கூடிய agents-ஐ பட்டியலிடு
const agents = await client.app.agents()

Project

MethodDescriptionResponse
project.list()அனைத்து திட்டங்களையும் பட்டியலிடுProject[]
project.current()தற்போதைய திட்டத்தைப் பெறுProject

எடுத்துக்காட்டுகள்

// அனைத்து திட்டங்களையும் பட்டியலிடு
const projects = await client.project.list()

// தற்போதைய திட்டத்தைப் பெறு
const currentProject = await client.project.current()

Path

MethodDescriptionResponse
path.get()தற்போதைய பாதையைப் பெறுPath

எடுத்துக்காட்டுகள்

// தற்போதைய பாதை தகவலைப் பெறு
const pathInfo = await client.path.get()

Config

MethodDescriptionResponse
config.get()கட்டமைப்பு தகவலைப் பெறுConfig

எடுத்துக்காட்டுகள்

const config = await client.config.get()

Sessions

MethodDescriptionNotes
session.list()அமர்வுகளை பட்டியலிடுReturns Session[]
session.get({ path })அமர்வைப் பெறுReturns Session
session.children({ path })குழந்தை அமர்வுகளை பட்டியலிடுReturns Session[]
session.create({ body })அமர்வை உருவாக்குReturns Session
session.delete({ path })அமர்வை நீக்குReturns boolean
session.update({ path, body })அமர்வு பண்புகளை புதுப்பிReturns Session
session.init({ path, body })பயன்பாட்டை பகுப்பாய்வு செய்து AGENTS.md உருவாக்குReturns boolean
session.abort({ path })இயங்கும் அமர்வை நிறுத்துReturns boolean
session.summarize({ path, body })அமர்வை சுருக்கவும்Returns boolean
session.messages({ path })ஒரு அமர்வில் உள்ள செய்திகளை பட்டியலிடுReturns { info: Message, parts: Part[]}[]
session.message({ path })செய்தி விவரங்களைப் பெறுReturns { info: Message, parts: Part[]}
session.prompt({ path, body })Prompt செய்தியை அனுப்புbody.noReply: true returns UserMessage (context only). Default returns AssistantMessage with AI response. Supports body.outputFormat for structured output
session.command({ path, body })அமர்வுக்கு கட்டளையை அனுப்புReturns { info: AssistantMessage, parts: Part[]}
session.shell({ path, body })ஒரு shell கட்டளையை இயக்குReturns AssistantMessage
session.revert({ path, body })ஒரு செய்தியை மீட்டமைக்கவும்Returns Session
session.unrevert({ path })மீட்டமைக்கப்பட்ட செய்திகளை மீட்டெடுReturns Session
postSessionByIdPermissionsByPermissionId({ path, body })ஒரு permission கோரிக்கைக்கு பதிலளிக்குReturns boolean

எடுத்துக்காட்டுகள்

// அமர்வுகளை உருவாக்கி நிர்வகிக்கவும்
const session = await client.session.create({
  body: { title: "My session" },
})

const sessions = await client.session.list()

// ஒரு prompt செய்தியை அனுப்பு
const result = await client.session.prompt({
  path: { id: session.data.id },
  body: {
    model: { providerID: "dropstone", modelID: "dropstone-pro" },
    parts: [{ type: "text", text: "Hello!" }],
  },
})

// AI பதிலைத் தூண்டாமல் சூழலை செருகு (plugins-க்கு பயனுள்ளது)
await client.session.prompt({
  path: { id: session.data.id },
  body: {
    noReply: true,
    parts: [{ type: "text", text: "You are a helpful assistant." }],
  },
})

Files

MethodDescriptionResponse
find.text({ query })கோப்புகளில் உரையைத் தேடுArray of match objects with path, lines, line_number, absolute_offset, submatches
find.files({ query })பெயரால் கோப்புகள் மற்றும் கோப்புறைகளைக் கண்டறிstring[] (paths)
find.symbols({ query })பணியிட குறியீடுகளைக் கண்டறிSymbol[]
file.read({ query })ஒரு கோப்பைப் படிக்கவும்{ type: "raw" | "patch", content: string }
file.status({ query? })கண்காணிக்கப்பட்ட கோப்புகளுக்கான நிலையைப் பெறுFile[]

find.files சில விருப்ப query புலங்களை ஆதரிக்கிறது:

  • type: "file" அல்லது "directory"
  • directory: தேடலுக்கான திட்ட மூலத்தை மேலெழுது
  • limit: அதிகபட்ச முடிவுகள் (1–200)

எடுத்துக்காட்டுகள்

// கோப்புகளைத் தேடி படிக்கவும்
const textResults = await client.find.text({
  query: { pattern: "function.*dropstone" },
})

const files = await client.find.files({
  query: { query: "*.ts", type: "file" },
})

const directories = await client.find.files({
  query: { query: "packages", type: "directory", limit: 20 },
})

const content = await client.file.read({
  query: { path: "src/index.ts" },
})

Auth

MethodDescriptionResponse
auth.set({ ... })அங்கீகார சான்றுகளை அமைக்கவும்boolean

எடுத்துக்காட்டுகள்

await client.auth.set({
  path: { id: "dropstone" },
  body: { type: "api", key: "your-dropstone-api-key" },
})

Events

MethodDescriptionResponse
event.subscribe()Server-sent events streamServer-sent events stream

எடுத்துக்காட்டுகள்

// நிகழ்நேர நிகழ்வுகளைக் கேளுங்கள்
const events = await client.event.subscribe()
for await (const event of events.stream) {
  console.log("Event:", event.type, event.properties)
}

v2 API

SDK ஒரு நிலையான v1 மேற்பரப்பை (மேலே உள்ள எடுத்துக்காட்டுகளில் பயன்படுத்தப்பட்டது) மற்றும் புதிய Effect HttpApi ஒப்பந்தத்தை பிரதிபலிக்கும் v2 மேற்பரப்பை வழங்குகிறது. புதிய ஒருங்கிணைப்புகளுக்கு v2-ஐ விரும்புங்கள்:

import { createDropstone } from "@blankline/dropstone-sdk/v2"

const { client, server } = await createDropstone()
// v2 ஒரு பணக்கார resource படிநிலையை வெளிப்படுத்துகிறது: workspace, worktree, file, find, போன்றவை.
const files = await client.file.list({ path: "src" })

v1 மேற்பரப்பு பின்னோக்கி இணக்கத்திற்காக வைக்கப்படுகிறது. புதிய endpoints v2-இல் மட்டுமே சேர்க்கப்படுகின்றன.

Ctrl+I